A query : C++

T

Thomas Richter

Yes it does. Unless you recompile all compilation
units which include this class definition then you
are violating the ODR (one-definition rule) and the
program has undefined behavior.

Does it? Isn't a compiler allowed to pull class definitions
from somewhere else if it sees for example an #include<string>?

In other words, AFAIK editing an include file that describes
components of the standard library might not necessarely
show *any* effect at all because the compiler isn't required
to read the file in first place - it could be just a dummy.

Not that I'm aware of any implementation that does this right
now...

So long,
Thomas
 
F

Francis Glassborow

We have two kinds of linkages : internal and external linkages. In
internal linkages, the scope of the function or variable is limited to
the current translational unit. ( current .cpp file which the complier
is currently compliling to object file ) These functions or variables
cannot be accessed in other translational units.

So, cannot the complier make all private variables and functions
default to internal linkage and limit it accessing from any other
translational unit?

Among other things, because there is no requirement that the whole
implementation of a class be in the same TU. We really do not want to
mess with this area of C++. The 'experts' looking at issues of
initialisation etc. are finding themselves surprised enough already.
 
A

Allan W

Hyman said:
Yes it does. ....
program has undefined behavior.

The definition of "Undefined behavior" is: the behavior (what
will happen) is not defined (the standard doesn't say). So by
definition, the standard doesn't say what will happen when you
have UB.
The compiler is not
required to diagnose this, but a high-quality
implementation would, presumably by incorporating a
hash of the class definition text into the mangled
name of the class so that the proposed change would
cause link failure.

I've used compilers that I personally considered high-quality.
Lots (most?) compilers incorporate the types of function
parameters into the "mangled name" of the function to allow for
overloading -- but I've yet to see one that changed any names
based on the number and types of class members, much less the
access specifiers.

Would you please tell me the name of one of the high-quality
implementations that do that?
 
K

kanze

Michael said:
Chetan Raj wrote:
I don't see a problem with this. Recall that the relative
offset of an attribute in an object is known in compile time,
and the compiler can easily create direct access to it.

Changing a privat to a public can change the layout of the
class. I don't know of any compiler where it does, of course,
but the standard explictly allows it. Presumably, there could
be a compiler which puts all private members at the start of the
class.

Anytime different compilation units see different versions of a
class, you have undefined behavior. Anytime you change anything
in a class defined by the standard, you have undefined behavior.

Of course, that doesn't mean you can't get away with it in some,
or even in most implementations.
Notice that you can also gain access to private attributes
(data members) using a debugger!-)

If you know the physical layout of a class (and with a bit of
creative dumping, it usually isn't very difficult to figure
out), you can access anything in the class directly in your
program by some creative use of pointer casts and pointer
arithmetic. James Coplien even once explained how to change the
vptr (thus effectively changing the type of the object) on the
fly. He made it very clear, however, that this wasn't something
you could do portably, and that it wasn't for the faint of
heart.
C++ gives you access control only if you follow the
guidelines, this is similar to the road where you can almost
always ignore the rules and drive your SUV in a different way.
If you want to better hide your data, you need to put it on
a different computer and control the traffic on it.

That's an interesting idea. An implementation of std::vector
which keeps its data on another machine, with an operator[]
which sends a request, and waits for the answer. I'm pretty
sure that such an implementation wouldn't be conforming, but
even if it were, I doubt that the performance would be
quite what most users expect:).
 
K

kanze

Does it?
Yes.

Isn't a compiler allowed to pull class definitions from
somewhere else if it sees for example an #include<string>?
Yes.

In other words, AFAIK editing an include file that describes
components of the standard library might not necessarely show
*any* effect at all because the compiler isn't required to
read the file in first place - it could be just a dummy.

Which is one possible behavior of undefined behavior. Undefined
behavior is when the standard doesn't say anything about what
might happen. The code might compile and work correctly. Or it
might reformat your hard disk, or cause your computer to catch
fire. Or just about anything in between. (For some strange
reason, the behavior I've seen most often is that the code
compiles and runs perfectly in all of your tests, and then fails
miserably and very visibly in the demo for your most important
client. But the standard doesn't guarantee this behavior
either.)

One possible thing that can happen with undefined behavior is
that the implementation can define it. An obvious case of this
is Posix, which requires several things (well, at least one) to
work where the standard says that the behavior is undefined.
But I suspect that this is true of most systems, and probably
most compilers as well.
 
K

kanze

Yes it does. Unless you recompile all compilation units which
include this class definition then you are violating the ODR
(one-definition rule) and the program has undefined behavior.

But that's exactly what he said. Or do you see a difference
between "the standard doesn't say what will happen", and
"undefined behavior".
The compiler is not required to diagnose this, but a
high-quality implementation would, presumably by incorporating
a hash of the class definition text into the mangled name of
the class so that the proposed change would cause link
failure.

I agree, but by that measure, there are very few high-quality
implementations around.
 
K

kanze

Chetan said:
We have two kinds of linkages : internal and external
linkages. In internal linkages, the scope of the function or
variable is limited to the current translational unit. (
current .cpp file which the complier is currently compliling
to object file ) These functions or variables cannot be
accessed in other translational units.
So, cannot the complier make all private variables and
functions default to internal linkage and limit it accessing
from any other translational unit?
From any other translation unit except the one which includes
the header? I generally expect headers to be included by more
than one translation unit. Even the implementation will
normally be spread out over a number of different translation
units, one per function, if the object is not polymorphic.

Linkage affects names. External linkage means that the same
name (in the same scope) in different translation units refers
to the same thing. If the names within the class didn't have
external linkage, they would have to refer to different things
in different translation units. I don't see how this is
possible.
 
T

Thomas Richter

Hi James,

That was actually targetted at: "The standard doesn't say what
will happen here". Well, in some sense "Yes, it does say that
it doesn't give you any guarantee about what will happen". In
my understanding, this is rather a "No". But I guess we mean
the same. (-;
Which is one possible behavior of undefined behavior. Undefined
behavior is when the standard doesn't say anything about what
might happen. The code might compile and work correctly. Or it
might reformat your hard disk, or cause your computer to catch
fire. Or just about anything in between. (For some strange
reason, the behavior I've seen most often is that the code
compiles and runs perfectly in all of your tests, and then fails
miserably and very visibly in the demo for your most important
client. But the standard doesn't guarantee this behavior
either.)

(-: (-: Seems to be a pretty common behaivour for UB, indeed. (Fits
well into my experiences.)

Thanks,
Thomas
 
C

Class that cannot be inherited ... C++

hi
(with TCLITE)
When u will wanna some friend funtion
u have to declear that function as friend in the class declearation now
ur defination may be at the same point or "YOU WILL DEFINE THAT
FUNCTION IN .CPP FILE WITHOUT RESOLUTION OPERATOR" if u will not so (or
try with resolution) it will give an error at compile time "funtion is
not a part of class.
so its a completely different way to map its calling
and just changing the declearation will never go to work

i have read about virtual memory and vptr theory
if u get some theory for this friend function calling
please let me
thank u
Rahul Agarwal

// friend functions
#include <iostream.h>

class CRectangle {
int width, height;
public:
void set_values (int, int);
int area (void) {return (width * height);}
friend CRectangle duplicate (CRectangle);
};

void CRectangle::set_values (int a, int b) {
width = a;
height = b;
}

CRectangle duplicate (CRectangle rectparam)
{
CRectangle rectres;
rectres.width = rectparam.width*2;
rectres.height = rectparam.height*2;
return (rectres);
}

int main () {
CRectangle rect, rectb;
rect.set_values (2,3);
rectb = duplicate (rect);
cout << rectb.area();
}
 
C

Chetan Raj

Hi,

James said:
the header? I generally expect headers to be included by
more than one translation unit.

Header files contain the declaration and not the definitions for the
functions or the variables. So header files don't create storage. They
only indicate that storage will be available somewhere else. Now, when
the complier knows that a variable is private from the header file and
then when it comes across its (private variables) implementation in the
translational unit ( in .cpp file ), wouldn't the compiler have
sufficient information to make its linkage names internal.

Also,
Even the implementation will normally be spread out over a > number of different translation
units, one per function, if the object is not polymorphic.

The complier can know that the current translational unit does not have
the complete definition of the class. Now, cannot the compiler flag
this information somewhere, and when it sees another translational unit
which continues the implementation of the class, cannot it use the
flagged information?

Or, For this particular case of different translational units for the
same class, cannot we come up with another linkage scheme where the
variable names will be exposed only to those translational units
implementing a particular class.

Regards,
Chetan Raj
 
A

Allan W

Class that cannot be inherited ... C++

I suppose this was supposed to be the subject line, not the
"From" name... if I read the message right, your name is Rahul Agarwal.

Rahul said:
hi
(with TCLITE)
When u will wanna some friend funtion
u have to declear that function as friend in the class declearation now
ur defination may be at the same point or "YOU WILL DEFINE THAT
FUNCTION IN .CPP FILE WITHOUT RESOLUTION OPERATOR" if u will not so (or
try with resolution) it will give an error at compile time "funtion is
not a part of class.
so its a completely different way to map its calling
and just changing the declearation will never go to work

i have read about virtual memory and vptr theory
if u get some theory for this friend function calling
please let me
thank u
Rahul Agarwal

Ouch. I really really don't want to violate moderation guidelines,
but after six times trying to read that, my eyes hurt. At least some
of the misspellings (wanna,u) seem to be on purpose... please don't
do that!

Obviously you're asking some question about the program you attached.
I'll try to critique it.
// friend functions

This is the program name, yes?
#include <iostream.h>

This old-style header will work on some compilers...
better to use
class CRectangle {
int width, height;
public:
void set_values (int, int);
int area (void) {return (width * height);}
friend CRectangle duplicate (CRectangle);
};

I would have used a constructor instead of functin "set_values"
but we'll overlook that for now.
void CRectangle::set_values (int a, int b) {
width = a;
height = b;
}

Fine implementation of set_values.
CRectangle duplicate (CRectangle rectparam)
{
CRectangle rectres;
rectres.width = rectparam.width*2;
rectres.height = rectparam.height*2;
return (rectres);
}

If your class had a constructor, you could have written this a LOT
more simply... even without it, I don't quite understand why you
didn't just use set_values.

I would also recommend changing the parameter to a const reference,
if you're advanced enough to have read about references. (If not,
don't worry about it yet.)

The name "duplicate" makes me think that you wanted to make an
exact copy of the CRectangle. (This would be better as a copy
constructor, but that's a topic for another day.) I wonder why
you multiply the width and height by 2?
int main () {
CRectangle rect, rectb;
rect.set_values (2,3);
rectb = duplicate (rect);
cout << rectb.area();
}

rect is 2 by 3. When you use duplicate, you double both the width
and height by 2... the result is 4 by 6, so the total area is 24.

Still not sure what you were askikng... did I answer it?
 
H

Hyman Rosen

But that's exactly what he said. Or do you see a difference
between "the standard doesn't say what will happen", and
"undefined behavior".

Of course. The former implies that the standard has failed to
address the issue.
 
F

Francis Glassborow

Or, For this particular case of different translational units for the
same class, cannot we come up with another linkage scheme where the
variable names will be exposed only to those translational units
implementing a particular class.

Yes, of course we can but it is much more than a simple fix by tinkering
with linkage. If you take some time to look at the proposals for the
next version of C++, in particular
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1778.pdf on
modules which would seem to be a much better solution.
 
J

Jerry Coffin

Of course. The former implies that the standard has failed to
address the issue.

But the standard fairly specifically says that failing to address
behavior in a particular circumstance means that circumstance gives
undefined behavior.
 
H

Hyman Rosen

Jerry said:
But the standard fairly specifically says that failing to address
behavior in a particular circumstance means that circumstance gives
undefined behavior.

Yes, but there is still a difference between the standard saying that
something causes undefined behavior and saying nothing, allowing that
behavior to be undefined by what you say. It's not a difference that
matters to the program, but it is a factual difference in what the
standard contains. When you say that the standard "says nothing about"
something, it means that there is no bit of text in the standard which
addresses the question. That's different from the standard containing
that bit of text which says something is undefined behavior.
 
J

James Kanze

Hyman said:
(e-mail address removed) wrote:
Of course. The former implies that the standard has failed to
address the issue.

That's a loaded way of expressing it. While I think you and I
agree that there is a lot of "undefined behavior" which could be
defined, and that the language would be better off for it, the
fact remains that in most, if not all, cases of undefined
behavior and certainly in all where the standard explicitly says
that the behavior is undefined, the authors of the standard did
consider the issue, and decided intentionally that the behavior
should be undefined. This is not "failing to address the
issue"; even if in certain cases, it is "failing to address it
in the way I want".
 
J

James Kanze

Chetan said:
James Kanze wrote:
Header files contain the declaration and not the definitions
for the functions or the variables. So header files don't
create storage. They only indicate that storage will be
available somewhere else. Now, when the complier knows that a
variable is private from the header file and then when it
comes across its (private variables) implementation in the
translational unit ( in .cpp file ), wouldn't the compiler
have sufficient information to make its linkage names
internal.

Private variables can only be member variables. In such cases,
the compiler never creates storage for the individual variable,
only for the class (and that, only when an object of the class
is defined -- a class definition doesn't create any storage).
What it does, however, is define a layout of the class. And
that layout depends on the size and the order of member
variables. Private or public.

It is, of course, possible to conceive of a system where the
layout would only be known at link time. Such a system,
however, is either beyond the capacity of most current linkers,
or imposes undo runtime overhead.
The complier can know that the current translational unit does
not have the complete definition of the class. Now, cannot
the compiler flag this information somewhere, and when it sees
another translational unit which continues the implementation
of the class, cannot it use the flagged information?

At the very least, the compiler must know how big the object is,
in order for you to define a variable of its type.
Or, For this particular case of different translational units
for the same class, cannot we come up with another linkage
scheme where the variable names will be exposed only to those
translational units implementing a particular class.

One can doubtlessly think of a number of different
alternatives. Are they as simple as the present one? And if
not, are they worth it? I'd have to see the precise
alternative, in detail, to answer that, but I'm sceptical. I
rather suspect that if there had been a solution which is as
simple, but significantly better, someone would already have
thought of it, and presented it.
 
J

Jerry Coffin

[email protected] says... said:
Yes, but there is still a difference between the standard saying that
something causes undefined behavior and saying nothing, allowing that
behavior to be undefined by what you say.

Yes, but there is still a difference between "the standard has failed
to address the issue" and "I don't particularly care for the manner
in which the standard addresses the issue."
 
C

Chetan Raj

Hi Francis,

I read about the proposal to use C++ modules. (
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1778.pdf )

I have the following questions to ask..

1.Is this just a proposal or is it already accepted for the next C++
Standard?

2. When is the next C++ Standard expected to come out?

3. What are the other major features of next C++ Standard?

4. Does it still thrive to support C and hence risk type safety or
would it be more strict about type safety issues?

5. What are the changes/or new features in next C++ Standard Library?
Will boost library be included as a standard?

6. Is there a specific version number or code name for the next C++
Standard? ( By what name should I call the next C++ Standard? )

Thanks,
Chetan Raj
 
F

Francis Glassborow

Hi Francis,

I read about the proposal to use C++ modules. (
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1778.pdf )

I have the following questions to ask..

1.Is this just a proposal or is it already accepted for the next C++
Standard?

No, like almost everything currently on the table, it is just a
proposal.
2. When is the next C++ Standard expected to come out? 2009

3. What are the other major features of next C++ Standard?
Browse the papers. But Concepts and a new memory model are among the
more interesting.
4. Does it still thrive to support C and hence risk type safety or
would it be more strict about type safety issues?

Neither C nor C++ will gratuitously add incompatibilities but all that
means is that breaking compatibility is just one of several costs taken
into account when considering changes.
5. What are the changes/or new features in next C++ Standard Library?
Will boost library be included as a standard?

Look at TR1 and check work on TR2 (both Library items) And, no, Boost as
a whole will not be incorporated into the Standard.
6. Is there a specific version number or code name for the next C++
Standard? ( By what name should I call the next C++ Standard? )

We generally code it as C++0X
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,204
Messages
2,571,066
Members
47,672
Latest member
svaraho

Latest Threads

Top