Topic: Forward declaration of a class as a struct


Author: James Kanze <kanze@alex.gabi-soft.de>
Date: Tue, 21 May 2002 18:36:32 GMT
Raw View
Gennaro Prota <gennaro_prota@yahoo.com> writes:

|>  >I'm not sure. In the context of a standard, one might argue that
|>  >the word "thus" shouldn't be their. However, I think this
|>  >particular word is often used as a simple joiner, to make text
|>  >flow together more naturally, and not for its literal meaning.
|>  >(Words with similar literal meanings, "alors" and "doch", are
|>  >also used this way in French and German, so this seems to be a
|>  >rather universal situation.)

|>  Yes, the important thing here is to not interpret it as
|>  "therefore".

|>  / off-topic

|>  BTW the situation is the same in Italian: the words "dunque" or
|>  "allora" (which I guess is pretty much equivalent to the French
|>  "alors") may have the meaning of "therefore" or be just used as
|>  joiners. Indeed, for the first one the use as a joiner is by far
|>  the most common. For instance "Dunque, eccomi qua!" sounds pretty
|>  much as "Well, here I am!"; on the other hand, Descartes' "cogito
|>  ergo sum" is usually translated in Italian as "penso, dunque
|>  sono".

|>  / end off-topic

|>  In any case the use as interjection is quite colloquial, but maybe
|>  this is not the same in English.

I don't think I would consider it colloquial.  A sequence of
sentences, without any joiners, would sound awkward and stilted.  A
native English writer would automatically insert a joiner here and
there, to make it sound more natural.  And a native English reader
would automatically recognize them for what they are, and eliminate
them when determining the meaning.

In the case of an international standard, I think that consideration
should be given to the fact that it will be read and interpreted by
many non-native speakers.  But it isn't an easy thing to do, since the
native interpretation is, by definition, natural and intuitive.  I
can't imagine a native writer actually reflecting, and thinking, that
he must insert a joiner; he just does it.

--=20
James Kanze                                mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
                    Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(0)179 2607481

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: James Kanze <kanze@alex.gabi-soft.de>
Date: Tue, 21 May 2002 18:36:21 GMT
Raw View
Steve Clamage <clamage@eng.sun.com> writes:

|>  On Fri, 17 May 2002, Helmut Zeisel wrote:

|>  > My posted example (using "union" in one translation unit and
|>  > "struct" in a different translation unit) is accepted by GCC
|>  > (using same name mangling for struct and union) but is rejected
|>  > by VC (using different name mangling for struct and union).

|>  > As I understand, VC is right, and strictly according to the
|>  > standard GCC accepts an ill-formed program. The only (?) way to
|>  > detect errors of that kind would be to use different name
|>  > mangling. So the standard does not only allow different name
|>  > mangling for struct and union, it requires different name
|>  > mangling.

|>  No, the code is invalid, but the error is a violation of the
|>  One-Definition Rule, which does not need to be diagnosed. Both
|>  compilers comply with the standard in that regard.

I'm pretty sure that that is the intent (that this case be undefined
behavior), but I don't quite see how the one definition rule can apply
-- there *is* only one definition here; what we are talking about is
multiple, invalid declarations.

--=20
James Kanze                                mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
                    Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(0)179 2607481

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Gennaro Prota <gennaro_prota@yahoo.com>
Date: Wed, 15 May 2002 17:59:04 GMT
Raw View
On Mon, 13 May 2002 17:35:13 GMT, James Kanze
<kanze@alex.gabi-soft.de> wrote:

>Gennaro Prota <gennaro_prota@yahoo.com> writes:
>
>|>  On Wed,  8 May 2002 16:45:11 GMT, James Kanze
>|>  <kanze@alex.gabi-soft.de> wrote:
>
>|>  >Helmut Zeisel <atvai398@attglobal.net> writes:
>
>|>  >|>  Ron Natalie wrote:
>
>|>  >|>  > What about:
>
>|>  >|>  >         union A;
>|>  >|>  >         class A { };
>
>|>  >|>  > then?
>
>|>  >|>  In the ARM, Section 7.1.6, p. 112, I found
>
>|>  >|>  "If defined, a name declared using the *union* specifier must
>|>  >|>  be defined as a union. If defined, a name declared using the
>|>  >|>  *class* specifier must be defined using the class or struct
>|>  >|>  specifier.  If defined, a name declared using the *struct*
>|>  >|>  specifier must be defined using the class or struct
>|>  >|>  specifier. "
>
>|>  >|>  Is there something similar in the standard?
>
>|>  >7.1.5.3/3: "The class-key or enum keyword present in the
>|>  >    elaborated-type-specifier shall agree in kind with the declaration
>|>  >    to which the name in the elaborated-type-specifier refers.  This
>|>  >    rule also applies to the form of elaborated-type-specifier that
>|>  >    decalres a class-name or friend class since it can be construed as
>|>  >    referring to the definition of the class.  Thus, in any
>|>  >    elaborated-type-specifier, the enum keayword shall be used to
>|>  >    refer to an enumeration, the union class-key shall be used to
>|>  >    refer to a union, and either class or struct class-key shall be
>|>  >    used to refer to a class declared using the class or struct
>|>  >    class-key."
>
>|>  I don't have (at this moment) enough time to go into the standard
>|>  and make (I hope) my ideas clear but the sentences you quote are
>|>  very different from the ARM ones: what appears in a class
>|>  definition before { member-specificationopt } isn't an
>|>  elaborated-type-specifier.
>
>I don't think that they are that different.  The standard uses a more
>complex language, but I think that in the end, the effect is pretty
>much the same.


Yes, now that I managed to find the time to read them carefully (I'm a
dull pupil, I know :)) I agree with you. What lead me initially off
the track was that I tried to see in the standard explicit statements
about  the class-key to use in the definition (like the ARM ones). It
indeed says which to use, but the emphasis is on the declarations,
rather than on the definition (In this case the overall result is the
same, of course, but I didn't see that, and erroneusly supposed BTW
that you thought a definition involves an elaborated-type-specifier...
I hope my english is clear enough).


Ok so far... now a question and a note:

a) Provided that the class is never defined, is this legal?

    struct A;
    union A; // correct as long as you don't define A?

b) Note:

Since there are other places (other than declarations) where
elaborated-type-specifiers appear, there are implications of 7.1.5.3/3
that are not in the passage of the ARM quoted above, e.g.:

union X { int a; char b; };

void g(int X)
{
    // must use union here (this is not a declaration:
    //  it refers to the union defined above)
    //
    union X* p = ... ;
    ...
    p->a = X;
}


>|>  (BTW another difference with the ARM is that the standard allows:
>
>|>  struct A;
>|>  class A {};
>
>|>  or viceversa)
>
>That is legal both according to the ARM and according to the standard.

Right. My mistake in reading the ARM quote :(

> (Things would be a lot clearer if the standard
>hadn't insisted on saying that a union is a class, since a class
>defined with a union specifier is something entirely different than
>other classes.)

Yes, IMHO these kind of terminological choices are just a recipe for
errors. This is not an offence, but they closely resembles to me
obfuscated source code, with all the same drawbacks in terms of
comprehensibility (i.e. verification of correctness) and maintenance.
In one sense, it is against the least astonishment principle, if one
existed for language standards.

If a new term was convenient to mean "class or union" it could just be
invented, couldn't it?

Another example is (read to believe!) the one in 15p1: "within this
clause ``try block'' is taken to mean both try-block and
function-try-block" - gulp! :)


Genny.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Gennaro Prota <gennaro_prota@yahoo.com>
Date: Wed, 15 May 2002 19:14:46 GMT
Raw View
On Wed, 15 May 2002 17:59:04 GMT, Gennaro Prota
<gennaro_prota@yahoo.com> wrote:


>a) Provided that the class is never defined, is this legal?
>
>    struct A;
>    union A; // correct as long as you don't define A?

No, not legal. The first two sentences of 7.1.5.3/3 are enough to say
that: the second declaration refers to the first one, but the
class-key is incompatible. Sorry for the silly question.


Genny.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Allan_W@my-dejanews.com (Allan W)
Date: Thu, 16 May 2002 19:19:41 GMT
Raw View
James Kanze <kanze@alex.gabi-soft.de> wrote
> 7.1.5.3/3: "The class-key or enum keyword present in the
>     elaborated-type-specifier shall agree in kind with the declaration
>     to which the name in the elaborated-type-specifier refers.  This
>     rule also applies to the form of elaborated-type-specifier that
>     decalres a class-name or friend class since it can be construed as
>     referring to the definition of the class.  Thus, in any
>     elaborated-type-specifier, the enum keayword shall be used to
>     refer to an enumeration, the union class-key shall be used to
>     refer to a union, and either class or struct class-key shall be
>     used to refer to a class declared using the class or struct
>     class-key."

The first sentence seems to disagree with the last one.

IIRC, VC++6 rejects this code:

    class Foo;
    struct Foo { int i; };

with an error message specifically stating that if it was first
declared with class, it cannot be defined with struct (nor
vice-versa). This seems to agree with the first sentence quoted
above:
    The class-key or enum keyword present in the
    elaborated-type-specifier shall agree in kind
but not the last one:
    either class or struct class-key shall be used
    to refer to a class declared using the class
    or struct class-key.

Is VC++ right on this point?

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Allan_W@my-dejanews.com (Allan W)
Date: Thu, 16 May 2002 19:29:14 GMT
Raw View
Gennaro Prota <gennaro_prota@yahoo.com> wrote
> a) Provided that the class is never defined, is this legal?
>
>     struct A;
>     union A; // correct as long as you don't define A?

I don't know if it's legal, but it ought to be: because it seems
to me that the things you can do with an incomplete union are
precisely the same things you can do with an incomplete struct.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: James Kanze <kanze@alex.gabi-soft.de>
Date: Thu, 16 May 2002 19:53:16 GMT
Raw View
Allan_W@my-dejanews.com (Allan W) writes:

|>  James Kanze <kanze@alex.gabi-soft.de> wrote
|>  > 7.1.5.3/3: "The class-key or enum keyword present in the
|>  >     elaborated-type-specifier shall agree in kind with the declarat=
ion
|>  >     to which the name in the elaborated-type-specifier refers.  Thi=
s
|>  >     rule also applies to the form of elaborated-type-specifier that
|>  >     decalres a class-name or friend class since it can be construed=
 as
|>  >     referring to the definition of the class.  Thus, in any
|>  >     elaborated-type-specifier, the enum keayword shall be used to
|>  >     refer to an enumeration, the union class-key shall be used to
|>  >     refer to a union, and either class or struct class-key shall be
|>  >     used to refer to a class declared using the class or struct
|>  >     class-key."

|>  The first sentence seems to disagree with the last one.

It depends on what "agree in kind" means:-).  Given the later
sentences, and the fact that it doesn't say something like "declared
with the same keyword", I expect that "kind" here is a larger
categorization than the keyword in the declaration.

In fact, if we look at the list of types in 3.9.2, we see that there
is no struct type, and the class and struct define exactly the same
thing (whereas union is different -- it's a class, but it isn't).

(Looking at it closely, I suspect that a defect report is in order.
Although I think that the intent is clear, this section defines a
class as something "containing a sequence of objects [...]".  It then
says that a union is a class.  One of these statements is manifestly
wrong, because a union doesn't contain a sequence of objects, but
overlapping objects.)

|>  IIRC, VC++6 rejects this code:

|>      class Foo;
|>      struct Foo { int i; };

I am aware of this error.  In this case, there is no excuse, because
the situation hasn't changed since the ARM, and probably before.

|>  with an error message specifically stating that if it was first
|>  declared with class, it cannot be defined with struct (nor
|>  vice-versa). This seems to agree with the first sentence quoted
|>  above:
|>      The class-key or enum keyword present in the
|>      elaborated-type-specifier shall agree in kind

Both the class keyword and the struct keyword declare something of the
same kind.

|>  but not the last one:
|>      either class or struct class-key shall be used
|>      to refer to a class declared using the class
|>      or struct class-key.

|>  Is VC++ right on this point?

Definitly not.  The first sentence that I quoted, taken alone, is open
to various interpretations.  But the rule in interpretation is always
that specifics override generalities -- in this case, the specifics in
the last sentence make it quite clear that types declared with struct
and types declared with class are of the same kind.  (And since the
word "kind" isn't defined anywhere else, this is all we have to go on
with regards to what is meant.)

--=20
James Kanze                                mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
                    Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(0)179 2607481

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Gennaro Prota <gennaro_prota@yahoo.com>
Date: Thu, 16 May 2002 21:19:15 GMT
Raw View
On Thu, 16 May 2002 19:53:16 GMT, James Kanze
<kanze@alex.gabi-soft.de> wrote:

[...]

>In fact, if we look at the list of types in 3.9.2, we see that there
>is no struct type, and the class and struct define exactly the same
>thing (whereas union is different -- it's a class, but it isn't).
>
>(Looking at it closely, I suspect that a defect report is in order.
>Although I think that the intent is clear, this section defines a
>class as something "containing a sequence of objects [...]".  It then
>says that a union is a class.  One of these statements is manifestly
>wrong, because a union doesn't contain a sequence of objects, but
>overlapping objects.)

Yes and no. Even though I was tempted in the first place to say that
this demonstrates my "theory" :-) about weird terminologies (in one of
my other replies on this thread), I can't believe they falled into the
trap with two sentences so close each other. So I guess the idea
(which I don't like) is that a "sequence of objects" may have one
element and it doesn't need to have always the same type. In other
words a union is a sequence consisting of exactly one element whose
type differs at different times.

What do you think? (Yes... if I was a bad boy then that theory.... :)
)


>
>|>  IIRC, VC++6 rejects this code:
>
>|>      class Foo;
>|>      struct Foo { int i; };
>

It's only a warning (C4099)

>The first sentence that I quoted, taken alone, is open
>to various interpretations.  But the rule in interpretation is always
>that specifics override generalities -- in this case, the specifics in
>the last sentence make it quite clear that types declared with struct
>and types declared with class are of the same kind.  (And since the
>word "kind" isn't defined anywhere else, this is all we have to go on
>with regards to what is meant.)

Full agreement on this point. To me, but once again I think that's not
the case for a native english speaker, the word "thus" (which I see as
a synonym of "therefore") suggests a wrong direction from generalities
to specifics. On the other hand I can weaken the meaning of it to that
of a simple interjection like "well", but in that case I don't see
what is it doing in a standard document. Not so important anyway...I
realize that it is a kind of mental contorsion that no sane reader
would do, so I apologize for just regurgitating some thoughts that
come to my mind in these situations.


Genny.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: helmut.zeisel@aon.at (Helmut Zeisel)
Date: Fri, 17 May 2002 16:00:36 GMT
Raw View
Allan_W@my-dejanews.com (Allan W) wrote in message news:<23b84d65.0205161127.693929a0@posting.google.com>...
> Gennaro Prota <gennaro_prota@yahoo.com> wrote
> > a) Provided that the class is never defined, is this legal?
> >
> >     struct A;
> >     union A; // correct as long as you don't define A?
>
> I don't know if it's legal, but it ought to be: because it seems
> to me that the things you can do with an incomplete union are
> precisely the same things you can do with an incomplete struct.

===== File1.cpp:
union A;

void f(const A&);
typedef void (*tf)(const A&);

extern tf pf = &f;

===== File2.cpp:

struct A {};

void f(const A&) {}
typedef void (*tf)(const A&);

extern tf pf;

int main()
{
  A a;
  (*pf)(a);
};

=================

This code is not legal;
it will be legal, when you replace "union" by "struct" in the
File1.cpp;

Is it really necessary that the interface of

"void __cdecl f(struct A const &)"

is diffrent from the interface of

"void __cdecl f(union A const &)"?

Helmut

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: James Kanze <kanze@alex.gabi-soft.de>
Date: Fri, 17 May 2002 16:00:30 GMT
Raw View
Gennaro Prota <gennaro_prota@yahoo.com> writes:

|>  On Thu, 16 May 2002 19:53:16 GMT, James Kanze
|>  <kanze@alex.gabi-soft.de> wrote:

|>  [...]

|>  >In fact, if we look at the list of types in 3.9.2, we see that
|>  >there is no struct type, and the class and struct define exactly
|>  >the same thing (whereas union is different -- it's a class, but
|>  >it isn't).

|>  >(Looking at it closely, I suspect that a defect report is in
|>  >order.  Although I think that the intent is clear, this section
|>  >defines a class as something "containing a sequence of objects
|>  >[...]".  It then says that a union is a class.  One of these
|>  >statements is manifestly wrong, because a union doesn't contain a
|>  >sequence of objects, but overlapping objects.)

|>  Yes and no. Even though I was tempted in the first place to say
|>  that this demonstrates my "theory" :-) about weird terminologies
|>  (in one of my other replies on this thread), I can't believe they
|>  falled into the trap with two sentences so close each other. So I
|>  guess the idea (which I don't like) is that a "sequence of
|>  objects" may have one element and it doesn't need to have always
|>  the same type. In other words a union is a sequence consisting of
|>  exactly one element whose type differs at different times.

|>  What do you think? (Yes... if I was a bad boy then that
|>  theory.... :) )

I think that there is a need for clarification.  Personally, I think
that the problem stems from trying to define unions as a type of
class; to do so, you have to significantly loosen the definition of
class, and you also have to define a non-union class.  The authors of
the standard don't seem to have made up their mind about this -- when
they speak of class, they don't seem to be thinking of unions, but
when they speak of union, they definitly consider it to be a type of
class.

On the whole, however, I don't see it as a serious problem.  The
intent is clear as to what should and should not be allowed, once you
read the details, and whether unions are or are not "classes", in some
formal sense, doesn't affect the way I write a program, once I
understand what a class and a union really are.  The sloppy wording
isn't in the detailed specification which affects what I can and
cannot do.

|>  >|>  IIRC, VC++6 rejects this code:
|>  >
|>  >|>      class Foo;
|>  >|>      struct Foo { int i; };

|>  It's only a warning (C4099)

|>  >The first sentence that I quoted, taken alone, is open to various
|>  >interpretations.  But the rule in interpretation is always that
|>  >specifics override generalities -- in this case, the specifics in
|>  >the last sentence make it quite clear that types declared with
|>  >struct and types declared with class are of the same kind.  (And
|>  >since the word "kind" isn't defined anywhere else, this is all we
|>  >have to go on with regards to what is meant.)

|>  Full agreement on this point. To me, but once again I think that's
|>  not the case for a native english speaker, the word "thus" (which
|>  I see as a synonym of "therefore") suggests a wrong direction from
|>  generalities to specifics. On the other hand I can weaken the
|>  meaning of it to that of a simple interjection like "well", but in
|>  that case I don't see what is it doing in a standard document. Not
|>  so important anyway...I realize that it is a kind of mental
|>  contorsion that no sane reader would do, so I apologize for just
|>  regurgitating some thoughts that come to my mind in these
|>  situations.

I'm not sure.  In the context of a standard, one might argue that the
word "thus" shouldn't be their.  However, I think this particular word
is often used as a simple joiner, to make text flow together more
naturally, and not for its literal meaning.  (Words with similar
literal meanings, "alors" and "doch", are also used this way in French
and German, so this seems to be a rather universal situation.)

--=20
James Kanze                                mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
                    Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(0)179 2607481

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: James Kanze <kanze@alex.gabi-soft.de>
Date: Fri, 17 May 2002 16:38:45 GMT
Raw View
Allan_W@my-dejanews.com (Allan W) writes:

|>  Gennaro Prota <gennaro_prota@yahoo.com> wrote
|>  > a) Provided that the class is never defined, is this legal?

|>  >     struct A;
|>  >     union A; // correct as long as you don't define A?

|>  I don't know if it's legal, but it ought to be: because it seems
|>  to me that the things you can do with an incomplete union are
|>  precisely the same things you can do with an incomplete struct.

On the other hand, given these declarations, you cannot define the
type without an error, so they should be illegal (which I think they
are).

In fact, the problem isn't so much what *you* can do with the type,
but what the implementation needs to know for you to do it.  The
current rules are designed to allow the implementation to use a
different name mangling (or whatever) for each of the different types
described in 3.9.2.  I doubt that this freedom is really essential, or
that loosing it would be a serious handicap for implementors, but I
don't see anything that would be gained in return, either.

--=20
James Kanze                                mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
                    Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(0)179 2607481

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Gennaro Prota <gennaro_prota@yahoo.com>
Date: Fri, 17 May 2002 18:48:07 GMT
Raw View
On Fri, 17 May 2002 16:38:45 GMT, James Kanze
<kanze@alex.gabi-soft.de> wrote:

>Allan_W@my-dejanews.com (Allan W) writes:
>
>|>  Gennaro Prota <gennaro_prota@yahoo.com> wrote
>|>  > a) Provided that the class is never defined, is this legal?
>
>|>  >     struct A;
>|>  >     union A; // correct as long as you don't define A?
>
>|> [...]
>
>On the other hand, given these declarations, you cannot define the
>type without an error, so they should be illegal (which I think they
>are).

Well, that's my question ok, but I gave my answer too :) (Did it
appear on your servers?). The way I read 7.1.5.3/3

struct A;
union A;

is illegal even if you never define the class.

The sentence "either the class or struct class-key shall be used to
refer to a class (clause 9) declared using the class or struct
class-key" means, to me, that you cannot use keywords different from
'class' and 'struct' to refer to a class declared using 'struct'.


OTOH (forgive me! I'm quite fussy!) I'm not so sure about:

union A;
struct A;

I would be much more sure if "the union class-key shall be used to
refer to a union" was changed to "the union class-key shall be used to
refer to a class declared using union"

Genny.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Helmut Zeisel <zei2002@liwest.at>
Date: Fri, 17 May 2002 20:12:53 GMT
Raw View
James Kanze wrote:
>
> The
> current rules are designed to allow the implementation to use a
> different name mangling (or whatever) for each of the different types
> described in 3.9.2.  I doubt that this freedom is really essential, or
> that loosing it would be a serious handicap for implementors, but I
> don't see anything that would be gained in return, either.

This answers my question in my previous posting.

My posted example (using "union" in one translation unit and "struct"
in a different translation unit)
is accepted by GCC (using same name mangling for struct and union)
but is rejected by VC (using different name mangling for struct and
union).

As I understand, VC is right, and strictly according to the standard
GCC accepts an ill-formed program. The only (?)
way to detect errors of that kind
would be to use different name mangling.
So the standard does not only allow
different name mangling for struct and union,
it requires different name mangling.

Helmut

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Gennaro Prota <gennaro_prota@yahoo.com>
Date: Fri, 17 May 2002 22:19:10 GMT
Raw View
On Fri, 17 May 2002 16:00:30 GMT, James Kanze
<kanze@alex.gabi-soft.de> wrote:

>[...]
>
>I think that there is a need for clarification.  Personally, I think
>that the problem stems from trying to define unions as a type of
>class; to do so, you have to significantly loosen the definition of
>class, and you also have to define a non-union class.  The authors of
>the standard don't seem to have made up their mind about this -- when
>they speak of class, they don't seem to be thinking of unions, but
>when they speak of union, they definitly consider it to be a type of
>class.

Yes, mine was just a "psychic" attempt to perceive the intent of the
commitee (It's incredible to me that they incurred in a contradiction
between so close sentences). Anyhow, for more "distant" parts, I
imagine that they are usually written by different people in different
times. Now, if I, as author of, let's say, =A79p4 decide that a union
*is* a class, even though it's a class that is not a class, and is a
sequence of exactly one element etc...etc... then I'm just playing
with fire: other people working at the standard later may not make up
their mind about all the implications and intricacies of my
unintuitive terminology (when something is particularly involved and
artificial, it's very difficult to remember it without going into the
details each time; if I stay away from C++ for 6 months I'm pretty
sure I won't remember all the details of the conditional operator as I
do now (not that I remember everything :) ) but certainly I would keep
my ideas clear on access specifiers).

 In many respects the standard appears to me like a big program, and
readability and maintenability are two qualities that IMHO can only be
to advantage of the standard and the language themselves.

A choice like the one we are discussing here would be heavily
documented in a program. Now I don't know how it goes as it concerns
communication between different people working at the standard but the
point is that they are people, not gods, and I suspect that if there
was an equivalent of those comments, i.e. something saying: "Hey,
people! Be aware that when we say class we include unions as well, but
union are really different in the following aspects: ....", I think
someone would have suggested to change completely the wording. On the
other hand, if such warning didn't exist (no comment at all), I'm not
surprised that someone falled into the trap.

Be careful, we are substantially saying the same thing here. My
emphasis is on the fact that such terminologies should have never been
introduced into the standard. Correcting them now is substantially a
patch, and if it is the case to do that, it may well be a good lesson.

>I'm not sure.  In the context of a standard, one might argue that the
>word "thus" shouldn't be their.  However, I think this particular word
>is often used as a simple joiner, to make text flow together more
>naturally, and not for its literal meaning.  (Words with similar
>literal meanings, "alors" and "doch", are also used this way in French
>and German, so this seems to be a rather universal situation.)

Yes, the important thing here is to not interpret it as "therefore".

/ off-topic
/
BTW the situation is the same in Italian: the words "dunque" or
"allora" (which I guess is pretty much equivalent to the French
"alors") may have the meaning of "therefore" or be just used as
joiners. Indeed, for the first one the use as a joiner is by far the
most common. For instance "Dunque, eccomi qua!" sounds pretty much as
"Well, here I am!"; on the other hand, Descartes' "cogito ergo sum" is
usually translated in Italian as "penso, dunque sono".

/ end off-topic

In any case the use as interjection is quite colloquial, but maybe
this is not the same in English.

Genny.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Steve Clamage <clamage@eng.sun.com>
Date: Mon, 20 May 2002 17:12:14 GMT
Raw View
On Fri, 17 May 2002, Helmut Zeisel wrote:
>
> My posted example (using "union" in one translation unit and "struct"
> in a different translation unit)
> is accepted by GCC (using same name mangling for struct and union)
> but is rejected by VC (using different name mangling for struct and
> union).
>
> As I understand, VC is right, and strictly according to the standard
> GCC accepts an ill-formed program. The only (?)
> way to detect errors of that kind
> would be to use different name mangling.
> So the standard does not only allow
> different name mangling for struct and union,
> it requires different name mangling.

No, the code is invalid, but the error is a violation of
the One-Definition Rule, which does not need to be diagnosed.
Both compilers comply with the standard in that regard.

--
Steve Clamage, stephen.clamage@sun.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Gennaro Prota <gennaro_prota@yahoo.com>
Date: Mon, 20 May 2002 18:58:33 GMT
Raw View
On Mon, 20 May 2002 17:12:14 GMT, Steve Clamage <clamage@eng.sun.com>
wrote:

>No, the code is invalid, but the error is a violation of
>the One-Definition Rule, which does not need to be diagnosed.
>Both compilers comply with the standard in that regard.

Gulp! This thread is reserving a few surprises :-O

Do you mean that the error has nothing to do with 7.1.5.3/3?
In this case can you explain how the ODR rule is violated, considering
that pf is defined only in File1.cpp, while f and A are defined only
in File2.cpp?

Genny.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: James Kanze <kanze@alex.gabi-soft.de>
Date: Mon, 13 May 2002 17:35:13 GMT
Raw View
Gennaro Prota <gennaro_prota@yahoo.com> writes:

|>  On Wed,  8 May 2002 16:45:11 GMT, James Kanze
|>  <kanze@alex.gabi-soft.de> wrote:

|>  >Helmut Zeisel <atvai398@attglobal.net> writes:

|>  >|>  Ron Natalie wrote:

|>  >|>  > What about:

|>  >|>  >         union A;
|>  >|>  >         class A { };

|>  >|>  > then?

|>  >|>  In the ARM, Section 7.1.6, p. 112, I found

|>  >|>  "If defined, a name declared using the *union* specifier must
|>  >|>  be defined as a union. If defined, a name declared using the
|>  >|>  *class* specifier must be defined using the class or struct
|>  >|>  specifier.  If defined, a name declared using the *struct*
|>  >|>  specifier must be defined using the class or struct
|>  >|>  specifier. "

|>  >|>  Is there something similar in the standard?

|>  >7.1.5.3/3: "The class-key or enum keyword present in the
|>  >    elaborated-type-specifier shall agree in kind with the declarati=
on
|>  >    to which the name in the elaborated-type-specifier refers.  This
|>  >    rule also applies to the form of elaborated-type-specifier that
|>  >    decalres a class-name or friend class since it can be construed =
as
|>  >    referring to the definition of the class.  Thus, in any
|>  >    elaborated-type-specifier, the enum keayword shall be used to
|>  >    refer to an enumeration, the union class-key shall be used to
|>  >    refer to a union, and either class or struct class-key shall be
|>  >    used to refer to a class declared using the class or struct
|>  >    class-key."

|>  I don't have (at this moment) enough time to go into the standard
|>  and make (I hope) my ideas clear but the sentences you quote are
|>  very different from the ARM ones: what appears in a class
|>  definition before { member-specificationopt } isn't an
|>  elaborated-type-specifier.

I don't think that they are that different.  The standard uses a more
complex language, but I think that in the end, the effect is pretty
much the same.

|>  (BTW another difference with the ARM is that the standard allows:

|>  struct A;
|>  class A {};

|>  or viceversa)

That is legal both according to the ARM and according to the standard.

|>  When I will have a few time, I'll also try to think over that
|>  different treatment of class and struct in comparison to unions
|>  (note that your quote says "class or struct class-key shall be
|>  used to refer to a class DECLARED using..." while "the union
|>  class-key shall be used to refer to a union" (i.e. to a class
|>  DEFINED with the keyword union).

The reason is basically that class and struct define the same thing --
a class which is not a union.  Whereas union defines something
different: a union.  (Things would be a lot clearer if the standard
hadn't insisted on saying that a union is a class, since a class
defined with a union specifier is something entirely different than
other classes.)

--=20
James Kanze                                mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
                    Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(0)179 2607481

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Gennaro Prota <gennaro_prota@yahoo.com>
Date: Fri, 10 May 2002 03:03:04 GMT
Raw View
On Wed,  8 May 2002 16:45:11 GMT, James Kanze
<kanze@alex.gabi-soft.de> wrote:

>Helmut Zeisel <atvai398@attglobal.net> writes:
>
>|>  Ron Natalie wrote:
>
>|>  > What about:
>
>|>  >         union A;
>|>  >         class A { };
>
>|>  > then?
>
>|>  In the ARM, Section 7.1.6, p. 112, I found
>
>|>  "If defined, a name declared using the *union* specifier must be
>|>  defined as a union. If defined, a name declared using the *class*
>|>  specifier must be defined using the class or struct specifier.  If
>|>  defined, a name declared using the *struct* specifier must be
>|>  defined using the class or struct specifier. "
>
>|>  Is there something similar in the standard?
>
>7.1.5.3/3: "The class-key or enum keyword present in the
>    elaborated-type-specifier shall agree in kind with the declaration
>    to which the name in the elaborated-type-specifier refers.  This
>    rule also applies to the form of elaborated-type-specifier that
>    decalres a class-name or friend class since it can be construed as
>    referring to the definition of the class.  Thus, in any
>    elaborated-type-specifier, the enum keayword shall be used to
>    refer to an enumeration, the union class-key shall be used to
>    refer to a union, and either class or struct class-key shall be
>    used to refer to a class declared using the class or struct
>    class-key."

I don't have (at this moment) enough time to go into the standard and
make (I hope) my ideas clear but the sentences you quote are very
different from the ARM ones: what appears in a class definition before
{ member-specificationopt } isn't an elaborated-type-specifier. (BTW
another difference with the ARM is that the standard allows:

struct A;
class A {};

or viceversa)

When I will have a few time, I'll also try to think over that
different treatment of class and struct in comparison to unions (note
that your quote says "class or struct class-key shall be used to refer
to a class DECLARED using..." while "the union class-key shall be used
to refer to a union" (i.e. to a class DEFINED with the keyword union).


Genny.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Helmut Zeisel <zei2002@liwest.at>
Date: Thu, 2 May 2002 21:38:01 GMT
Raw View
Is it legal to do a forward declaration of a class as struct
(or vice versa)?

i.e. is the following code legal:

struct A;
class A;

It is accepted by GCC 2.95 and GCC 3.0; VC++ 6.0 gives a warning.
What does the standard say?

Helmut Zeisel

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: James Kanze <kanze@alex.gabi-soft.de>
Date: Fri, 3 May 2002 17:34:03 GMT
Raw View
Helmut Zeisel <zei2002@liwest.at> writes:

|>  Is it legal to do a forward declaration of a class as struct (or
|>  vice versa)?

|>  i.e. is the following code legal:

|>  struct A;
|>  class A;

|>  It is accepted by GCC 2.95 and GCC 3.0; VC++ 6.0 gives a warning.
|>  What does the standard say?

That it is legal.  Both key words, class and struct, define a class --
there is no such thing as a struct in C++.

--=20
James Kanze                                mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
                    Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(0)179 2607481

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Ron Natalie <ron@sensor.com>
Date: Fri, 3 May 2002 20:54:21 GMT
Raw View

James Kanze wrote:

> |>  It is accepted by GCC 2.95 and GCC 3.0; VC++ 6.0 gives a warning.
> |>  What does the standard say?
>
> That it is legal.  Both key words, class and struct, define a class --


What about:

 union A;
 class A { };

then?

Looks like it should be legal.  The standard says that the first
one of the form "class-key identifer" just introduces the identfier
as a class name.

> there is no such thing as a struct in C++.

Well then the stnadards people wasted a lot of effort defining it.

9/4:  A structure is a class defined with the class-key struct;
 its members and base classes are public by default.
      A union is a class defined with the class-key union.

struct(ure)s and unions are kinds of classes.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: James Kanze <kanze@alex.gabi-soft.de>
Date: Mon, 6 May 2002 10:54:45 GMT
Raw View
Ron Natalie <ron@sensor.com> writes:

|>  James Kanze wrote:

|>  > |>  It is accepted by GCC 2.95 and GCC 3.0; VC++ 6.0 gives a
|>  > |>  warning. What does the standard say?

|>  > That it is legal. Both key words, class and struct, define a
|>  > class --

|>  What about:

|>   union A;
|>   class A { };

|>  then?

|>  Looks like it should be legal. The standard says that the first
|>  one of the form "class-key identifer" just introduces the
|>  identfier as a class name.

Good question.  7.1.5.3 says no.  But I don't see any strong technical
reasons (implementation problems, etc.) to forbid it.  If you're going
to say that unions are classes, then it should be allowed.

|>  > there is no such thing as a struct in C++.

|>  Well then the stnadards people wasted a lot of effort defining it.

|>  9/4:  A structure is a class defined with the class-key struct;
|>   its members and base classes are public by default.
|>        A union is a class defined with the class-key union.

|>  struct(ure)s and unions are kinds of classes.

Not a lot of effort, but some effort.

If I write:

    struct X { int i ; } ;

is X a class type, or no?  Is is a different type than if I write

    class X { public : int i ; } :

?

Now replace struct with union, and ask the same questions. =20

I'm not sure that there is a conclusive answer, at least in the case
of union.  The standard does say that a union is a kind of class.  And
then goes on to say to describe it as something rather different.
Most of the rules concerning classes also apply to unions, and if the
union has a user defined constructor, it behaves in many ways more
like a class than like a POD-union, so it is difficult to say.
However, unlike the case of struct, there are cases where the rules
are different, even outside of the definition.

--=20
James Kanze                                mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
                    Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(0)179 2607481

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Helmut Zeisel <atvai398@attglobal.net>
Date: Tue, 7 May 2002 15:46:47 GMT
Raw View
Ron Natalie wrote:

> What about:
>
>         union A;
>         class A { };
>
> then?

In the ARM, Section 7.1.6, p. 112, I found

"If defined, a name declared using the *union* specifier must be defined
as a union. If defined, a name declared using the *class* specifier must
be defined using the class or struct specifier.
If defined, a name declared using the *struct* specifier must
be defined using the class or struct specifier. "

Is there something similar in the standard?

Helmut

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: rgetov@ultraheap.com (Radoslav Getov)
Date: Tue, 7 May 2002 15:54:30 GMT
Raw View
Helmut Zeisel <zei2002@liwest.at> wrote in message news:<3CD1ABD2.346D6036@liwest.at>...
> Is it legal to do a forward declaration of a class as struct
> (or vice versa)?
>
> i.e. is the following code legal:
>
> struct A;
> class A;
>
> It is accepted by GCC 2.95 and GCC 3.0; VC++ 6.0 gives a warning.
> What does the standard say?
>
> Helmut Zeisel

They should be equivalent according to the standard,
but not for VC60 - it threats them as different classes at
link time. So, pay attention to the warning.

Radoslav Getov
rgetov@ultraheap.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: James Kanze <kanze@alex.gabi-soft.de>
Date: Wed, 8 May 2002 16:45:11 GMT
Raw View
Helmut Zeisel <atvai398@attglobal.net> writes:

|>  Ron Natalie wrote:

|>  > What about:

|>  >         union A;
|>  >         class A { };

|>  > then?

|>  In the ARM, Section 7.1.6, p. 112, I found

|>  "If defined, a name declared using the *union* specifier must be
|>  defined as a union. If defined, a name declared using the *class*
|>  specifier must be defined using the class or struct specifier.  If
|>  defined, a name declared using the *struct* specifier must be
|>  defined using the class or struct specifier. "

|>  Is there something similar in the standard?

7.1.5.3/3: "The class-key or enum keyword present in the
    elaborated-type-specifier shall agree in kind with the declaration
    to which the name in the elaborated-type-specifier refers.  This
    rule also applies to the form of elaborated-type-specifier that
    decalres a class-name or friend class since it can be construed as
    referring to the definition of the class.  Thus, in any
    elaborated-type-specifier, the enum keayword shall be used to
    refer to an enumeration, the union class-key shall be used to
    refer to a union, and either class or struct class-key shall be
    used to refer to a class declared using the class or struct
    class-key."

--=20
James Kanze                                mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
                    Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(0)179 2607481

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]