What would be the right warning/error?

Discussion in 'C Programming' started by jacob navia, Jun 6, 2008.

  1. jacob navia

    jacob navia Guest

    Consider this code

    static typedef struct {
    int boo;
    } FOO;

    This provokes with MSVC:
    ------------------------------
    Microsoft (R) C/C++ Optimizing Compiler Version 14.00.50727.762 for x64
    Copyright (C) Microsoft Corporation. All rights reserved.

    tstruct.c
    tstruct.c(1) : error C2159: more than one storage class specified
    ------------------------------

    With gcc we have:
    ----------------------------
    root@ubuntu-vm:/tmp# gcc t.c
    t.c:1: error: multiple storage classes in declaration specifiers
    ----------------------------

    With lcc-win I had
    Warning tstruct.c: 1 multiple types in a declaration. Last will be
    used: 'typedef'

    with lcc-win64
    ------------------------------
    Warning tstruct.c: 1 multiple use of 'typedef'
    ------------------------------

    All those warnings are misleading in my opinion. I have changed the
    wording to:
    Warning tstruct.c: 1 typedefs can't be static. Static keyword ignored

    I think that this is much more clear but I have now some doubts:

    Is this true?

    My reasoning is that the static keyword can only apply to an
    object, and a typedef is not an object. (Obviously there is
    another obscure meaning to "static". Let's leave that for now)

    Another problem is that both msvc and gcc say something about
    "multiple storage classes" that I can't understand. Why that?

    Note too that lcc-win issues just a warning. The other two issue
    an error and compilation fails. Is this such a bad error that
    warrants a failure to compiler the code?


    --
    jacob navia
    jacob at jacob point remcomp point fr
    logiciels/informatique
    http://www.cs.virginia.edu/~lcc-win32
     
    jacob navia, Jun 6, 2008
    #1
    1. Advertising

  2. jacob navia

    Bartc Guest

    "jacob navia" <> wrote in message
    news:g2bjun$9qp$...
    > Consider this code
    >
    > static typedef struct {
    > int boo;
    > } FOO;
    >
    > This provokes with MSVC:
    > ------------------------------
    > Microsoft (R) C/C++ Optimizing Compiler Version 14.00.50727.762 for x64
    > Copyright (C) Microsoft Corporation. All rights reserved.
    >
    > tstruct.c
    > tstruct.c(1) : error C2159: more than one storage class specified



    > Another problem is that both msvc and gcc say something about
    > "multiple storage classes" that I can't understand. Why that?


    I think that typedef is itself considered a storage class specifier (like
    static), for purposes of syntax. And presumably you're only allowed one at a
    time:

    static int *a[10]; /* declares a variable a with static storage */
    typedef int *b[10]; /* declares a type alias b */


    --
    Bartc
     
    Bartc, Jun 6, 2008
    #2
    1. Advertising

  3. jacob navia

    Guest

    On Jun 6, 8:09 am, jacob navia <> wrote:
    > Consider this code
    >
    > static typedef struct {
    > int boo;
    >
    > } FOO;
    >
    > This provokes with MSVC:
    > ------------------------------
    > Microsoft (R) C/C++ Optimizing Compiler Version 14.00.50727.762 for x64
    > Copyright (C) Microsoft Corporation. All rights reserved.
    >
    > tstruct.c
    > tstruct.c(1) : error C2159: more than one storage class specified
    > ------------------------------
    >
    > With gcc we have:
    > ----------------------------
    > root@ubuntu-vm:/tmp# gcc t.c
    > t.c:1: error: multiple storage classes in declaration specifiers
    > ----------------------------
    >
    > With lcc-win I had
    > Warning tstruct.c: 1 multiple types in a declaration. Last will be
    > used: 'typedef'
    >
    > with lcc-win64
    > ------------------------------
    > Warning tstruct.c: 1 multiple use of 'typedef'
    > ------------------------------
    >
    > All those warnings are misleading in my opinion. I have changed the
    > wording to:
    > Warning tstruct.c: 1 typedefs can't be static. Static keyword ignored
    >
    > I think that this is much more clear but I have now some doubts:
    >
    > Is this true?


    Is what true? That the warnings are misleading? Well, "uninformative"
    perhaps. That your warning is more explicit? Sure, okay. That typedefs
    can't be static? Yes.

    > My reasoning is that the static keyword can only apply to an
    > object, and a typedef is not an object. (Obviously there is
    > another obscure meaning to "static". Let's leave that for now)
    >
    > Another problem is that both msvc and gcc say something about
    > "multiple storage classes" that I can't understand. Why that?


    I'm no compiler writer, but I'm guessing it's just the way the
    compiler parses the code. "typedef" isn't a storage class (I don't
    think <duck>), but it's certainly not a type either, which is what
    would otherwise be required after that "static". I've seen many
    compiler errors and warnings that are _far_ more obscure than this.

    > Note too that lcc-win issues just a warning. The other two issue
    > an error and compilation fails. Is this such a bad error that
    > warrants a failure to compiler the code?


    Unless, as an extension, you document that construct to mean something
    useful, I see no reason to allow the code to compile. It's almost
    meaningless as it stands, won't compile on at least a couple of other
    mainstream compilers, and is so simply fixed that a hard error seems
    appropriate to me.

    --

    Cris
     
    , Jun 6, 2008
    #3
  4. jacob navia

    Guest

    On Jun 6, 8:44 am, wrote:
    > On Jun 6, 8:09 am, jacob navia <> wrote:
    >
    >
    >
    > > Consider this code

    >
    > > static typedef struct {
    > > int boo;

    >
    > > } FOO;

    >
    > > This provokes with MSVC:
    > > ------------------------------
    > > Microsoft (R) C/C++ Optimizing Compiler Version 14.00.50727.762 for x64
    > > Copyright (C) Microsoft Corporation. All rights reserved.

    >
    > > tstruct.c
    > > tstruct.c(1) : error C2159: more than one storage class specified
    > > ------------------------------

    >
    > > With gcc we have:
    > > ----------------------------
    > > root@ubuntu-vm:/tmp# gcc t.c
    > > t.c:1: error: multiple storage classes in declaration specifiers
    > > ----------------------------

    >
    > > With lcc-win I had
    > > Warning tstruct.c: 1 multiple types in a declaration. Last will be
    > > used: 'typedef'

    >
    > > with lcc-win64
    > > ------------------------------
    > > Warning tstruct.c: 1 multiple use of 'typedef'
    > > ------------------------------


    <snip>

    > > Another problem is that both msvc and gcc say something about
    > > "multiple storage classes" that I can't understand. Why that?

    >
    > I'm no compiler writer, but I'm guessing it's just the way the
    > compiler parses the code. "typedef" isn't a storage class (I don't
    > think <duck>),


    <snip>

    Oops, and thirty seconds after posting, I look it up, and lo and
    behold, "typedef" _is_ a storage class specifier ...

    Sigh.

    --

    Cris
     
    , Jun 6, 2008
    #4
  5. [My posts via rr.com still aren't showing up on aioe.org, so I'm
    posting this through aioe.org so jacob can see it. I'm continuing
    to post most of my articles through rr.com]

    jacob navia <> writes:
    > Consider this code
    >
    > static typedef struct {
    > int boo;
    > } FOO;
    >
    > This provokes with MSVC:
    > ------------------------------
    > Microsoft (R) C/C++ Optimizing Compiler Version 14.00.50727.762 for x64
    > Copyright (C) Microsoft Corporation. All rights reserved.
    >
    > tstruct.c
    > tstruct.c(1) : error C2159: more than one storage class specified
    > ------------------------------
    >
    > With gcc we have:
    > ----------------------------
    > root@ubuntu-vm:/tmp# gcc t.c
    > t.c:1: error: multiple storage classes in declaration specifiers
    > ----------------------------


    Both of those seem reasonable.

    > With lcc-win I had
    > Warning tstruct.c: 1 multiple types in a declaration. Last will be
    > used: 'typedef'
    >
    > with lcc-win64
    > ------------------------------
    > Warning tstruct.c: 1 multiple use of 'typedef'
    > ------------------------------
    >
    > All those warnings are misleading in my opinion. I have changed the
    > wording to:
    > Warning tstruct.c: 1 typedefs can't be static. Static keyword ignored
    >
    > I think that this is much more clear but I have now some doubts:
    >
    > Is this true?


    The warning is correct, as far as it goes, but the fact that your
    diagnostic *doesn't* refer to multiple storage classes makes me
    concerned that you might be missing some other cases.

    > My reasoning is that the static keyword can only apply to an
    > object, and a typedef is not an object. (Obviously there is
    > another obscure meaning to "static". Let's leave that for now)
    >
    > Another problem is that both msvc and gcc say something about
    > "multiple storage classes" that I can't understand. Why that?


    C99 6.7.1p3:

    The typedef specifier is called a storage-class specifier for
    syntactic convenience only; it is discussed in 6.7.7.

    > Note too that lcc-win issues just a warning. The other two issue
    > an error and compilation fails. Is this such a bad error that
    > warrants a failure to compiler the code?


    Absolutely. Issuing a warning for code with a constraint violation
    is, of course, permitted by the standard, but I can't imagine why
    you'd want to do so in this case. I see no benefit from allowing the
    user to leave this error uncorrected, or in blindly *guessing* that
    the last storage class is what was intended.

    You apparently treat this:
    static typedef int foo;
    as a typedef (ignoring "static"), and this:
    typedef static int foo;
    as a static object declaration. Both are simply errors.

    (In another thread, you do something equally arbitrary for type
    specifiers.)

    --
    Keith Thompson (The_Other_Keith) <>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Jun 6, 2008
    #5
  6. jacob navia

    jacob navia Guest

    Eric Sosman wrote:
    >> All those warnings are misleading in my opinion.

    >
    > The first two seem to me more precise than the latter two,
    > but I'll grant that they might mislead someone who didn't know
    > that `typedef' was a storage class. The number of such someones
    > may be non-negligible, hence the potential to mislead may be
    > non-negligible.
    >


    I didn't know that a typedef is a storage class. And now that
    the appropiate parts of the standard have been cited I still
    do not understand it.

    #define FOO 8

    the #define is not a storage class.

    A typedef is a compile time alias for another type. Why should it
    be a storage class?

    Mystery.



    --
    jacob navia
    jacob at jacob point remcomp point fr
    logiciels/informatique
    http://www.cs.virginia.edu/~lcc-win32
     
    jacob navia, Jun 6, 2008
    #6
  7. jacob navia

    jacob navia Guest

    Keith Thompson wrote:
    >
    > C99 6.7.1p3:
    >
    > The typedef specifier is called a storage-class specifier for
    > syntactic convenience only; it is discussed in 6.7.7.
    >


    Note:

    "FOR SYNTACTIC CONVENIENCE ONLY"

    typedefs are surely not a storage class!



    --
    jacob navia
    jacob at jacob point remcomp point fr
    logiciels/informatique
    http://www.cs.virginia.edu/~lcc-win32
     
    jacob navia, Jun 6, 2008
    #7
  8. jacob navia

    jacob navia Guest

    jacob navia, Jun 6, 2008
    #8
  9. jacob navia <> writes:
    > Eric Sosman wrote:
    >>> All those warnings are misleading in my opinion.

    >>
    >> The first two seem to me more precise than the latter two,
    >> but I'll grant that they might mislead someone who didn't know
    >> that `typedef' was a storage class. The number of such someones
    >> may be non-negligible, hence the potential to mislead may be
    >> non-negligible.
    >>

    >
    > I didn't know that a typedef is a storage class. And now that
    > the appropiate parts of the standard have been cited I still
    > do not understand it.


    As the standard clearly says, it's "for syntactic convenience only".

    I'm guessing that the inventor of "typedef" (presumably Dennis
    Ritchie) decided what he wanted a declaration to look like, then
    noticed that it fits exactly the same pattern as "static", "extern",
    et al. These two declarations:

    typedef int foo;
    static int foo;

    of course mean two very different things, but they follow exactly the
    same pattern, the only *syntactic* difference being the different
    keywords.

    The point is to make the language a bit easier to describe, and to
    make the job of compiler writers like you just a little bit simpler.

    > #define FOO 8
    >
    > the #define is not a storage class.


    Of course not. A macro definition is processed in a different
    translation phase, and it has very different syntax *and* semantics
    than either typedefs or (other) storage classes. There would be no
    benefit in treating it as a storage class.

    For a typedef, on the other hand, it's just *convenient* to use the
    same syntax as for other storage classes.

    Perhaps the standard would have been clearer if, rather than this:

    storage-class-specifier:
    typedef
    extern
    static
    auto
    register

    it had defined this:

    storage-class-specifier:
    extern
    static
    auto
    register

    storage-class-specifier-or-typedef:
    storage-class-specifier
    typedef

    and used "storage-class-specifier-or-typedef" wherever
    "storage-class-specifier" is used now. I'd probably advocate doing it
    that way if the existing definition weren't already well established,
    but once you understand what's going on, I don't find the existing
    definition to be all that troubling. But you could always use my
    proposed modification within your own compiler. Unless I've made a
    mistake, it will accept exactly the same set of syntactically valid
    translation units, and might make it a bit easier to generate clear
    diagnostics. But you can already do that by treating "typedef" as a
    special case of the set of storage classes.

    > A typedef is a compile time alias for another type. Why should it
    > be a storage class?


    See above.

    > Mystery.


    Not really.

    --
    Keith Thompson (The_Other_Keith) <>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Jun 6, 2008
    #9
  10. jacob navia <> writes:
    > Keith Thompson wrote:
    >>
    >> C99 6.7.1p3:
    >>
    >> The typedef specifier is called a storage-class specifier for
    >> syntactic convenience only; it is discussed in 6.7.7.
    >>

    >
    > Note:
    >
    > "FOR SYNTACTIC CONVENIENCE ONLY"


    YES, IT'S FOR SYNTACTIC CONVENIENCE ONLY. WHY ARE WE SHOUTING?

    > typedefs are surely not a storage class!


    The standard says they are. If you don't want to follow the
    standard's terminology, nobody is forcing you to do so. But I note
    that your failure to do so in this case has caused you to introduce a
    bug into your compiler. (By "bug" I don't necessarily mean a failure
    to conform to the standard's requirements.)

    --
    Keith Thompson (The_Other_Keith) <>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Jun 6, 2008
    #10
  11. jacob navia

    Serve Lau Guest

    "jacob navia" <> schreef in bericht
    news:g2bjun$9qp$...
    > Consider this code
    >
    > static typedef struct {
    > int boo;
    > } FOO;
    >
    > This provokes with MSVC:
    > ------------------------------
    > Microsoft (R) C/C++ Optimizing Compiler Version 14.00.50727.762 for x64
    > Copyright (C) Microsoft Corporation. All rights reserved.
    >
    > tstruct.c
    > tstruct.c(1) : error C2159: more than one storage class specified
    > ------------------------------
    >
    > With gcc we have:
    > ----------------------------
    > root@ubuntu-vm:/tmp# gcc t.c
    > t.c:1: error: multiple storage classes in declaration specifiers
    > ----------------------------
    >
    > With lcc-win I had
    > Warning tstruct.c: 1 multiple types in a declaration. Last will be
    > used: 'typedef'
    >
    > with lcc-win64
    > ------------------------------
    > Warning tstruct.c: 1 multiple use of 'typedef'
    > ------------------------------
    >
    > All those warnings are misleading in my opinion. I have changed the
    > wording to:
    > Warning tstruct.c: 1 typedefs can't be static. Static keyword ignored


    what if you say
    register typedef struct...
    or
    extern typedef struct...

    etc.

    I noticed that MSVC compiles the following with no complaints.

    const typedef struct {
    int boo;
    } FOO;

    Is that correct?
     
    Serve Lau, Jun 6, 2008
    #11
  12. In article <1212768389.979717@news1nwk>,
    Eric Sosman <> wrote:

    > It is true that there can be at most one storage class
    >specifier in a declaration, so you can't have `static typedef'.


    I think Jacob is right to try to give a more specific error message in
    this case. "typedef" may be a storage class as far as the standard is
    concerned, but that's just the standard-writer's trick for terseness,
    and an error message has other goals.

    -- Richard
    --
    In the selection of the two characters immediately succeeding the numeral 9,
    consideration shall be given to their replacement by the graphics 10 and 11 to
    facilitate the adoption of the code in the sterling monetary area. (X3.4-1963)
     
    Richard Tobin, Jun 6, 2008
    #12
  13. On Fri, 06 Jun 2008 19:46:48 +0200, Serve Lau wrote:
    > I noticed that MSVC compiles the following with no complaints.
    >
    > const typedef struct {
    > int boo;
    > } FOO;
    >
    > Is that correct?


    Yes. Declaration specifiers may be placed in any order. It means the exact
    same thing as

    typedef const struct {
    int boo;
    } FOO;

    However, "the placement of a storage-class specifier other than at the
    beginning of the declaration specifiers in a declaration is an obsolescent
    feature." And even if it weren't, you probably shouldn't do that, as
    there's no good reason (other than as part of a conformance test) for
    doing it.
     
    Harald van Dijk, Jun 6, 2008
    #13
  14. jacob navia

    Richard Guest

    CBFalconer <> writes:

    > jacob navia wrote:
    >>

    > ... snip ...
    >>
    >> #define FOO 8
    >>
    >> the #define is not a storage class.
    >>
    >> A typedef is a compile time alias for another type. Why should it
    >> be a storage class?

    >
    > #define p1 int*
    > typedef p2 int*;
    >
    > p1 a1, b1;
    > p2 a2, b2;
    >
    > note that a1, a2, and b2 are pointers. b1 is an int object.


    No they are not. p2 is nothing since it can not compile.

    I assume you mean something more like:

    typedef int * p2;
     
    Richard, Jun 6, 2008
    #14
  15. (Richard Tobin) writes:
    > In article <1212768389.979717@news1nwk>,
    > Eric Sosman <> wrote:
    >> It is true that there can be at most one storage class
    >>specifier in a declaration, so you can't have `static typedef'.

    >
    > I think Jacob is right to try to give a more specific error message in
    > this case. "typedef" may be a storage class as far as the standard is
    > concerned, but that's just the standard-writer's trick for terseness,
    > and an error message has other goals.


    Agreed.

    One cannot reasonably dispute that "typedef" is a
    "storage-class-specifier" *according to the standard* (since it's the
    standard that defines the term "storage-class-specifier"). But
    there's no requirement, and in this particular case perhaps no good
    reason, to use the standard's terminology in a diagnostic. The
    purpose of a diagnostic is to explain something to the user, with the
    goal of letting the user figure out how to correct the error.
    (Personally, I like seeing error messages that cite chapter and verse
    in the standard, but I'm not a typical user.)

    I don't know what kind of parser lcc-win (or it's predecessor lcc)
    uses internally. Presumably there's a description of the C grammar,
    either explicitly or implicitly. It's likely that this grammar
    follows the standard's grammar in treating "typedef" as a
    storage-class-specifier. But a little extra work to treat it as a
    special case when printing an error message would be worthwhile.

    Or, for that matter, the message could be something like "foo and bar
    may not be used in the same declaration", where foo and bar are
    replaced with whatever storage-class-specifiers appear in the
    incorrect code. In this case, there isn't even a need to mention
    storage-class specifiers. (Generating a reasonable diagnostic for
    three or more is left as an exercise.)

    --
    Keith Thompson (The_Other_Keith) <>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Jun 6, 2008
    #15
  16. jacob navia

    Richard Bos Guest

    jacob navia <> wrote:

    > Eric Sosman wrote:
    > >> All those warnings are misleading in my opinion.

    > >
    > > The first two seem to me more precise than the latter two,
    > > but I'll grant that they might mislead someone who didn't know
    > > that `typedef' was a storage class. The number of such someones
    > > may be non-negligible, hence the potential to mislead may be
    > > non-negligible.

    >
    > I didn't know that a typedef is a storage class.


    In a compiler implementor, that's scary.

    Richard
     
    Richard Bos, Jun 9, 2008
    #16
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Pete Becker
    Replies:
    0
    Views:
    1,377
    Pete Becker
    Feb 10, 2005
  2. B. Williams

    warning C4267 and warning C4996

    B. Williams, Oct 26, 2006, in forum: C++
    Replies:
    17
    Views:
    2,634
  3. jacob navia

    What would be the right decision?

    jacob navia, Jan 29, 2010, in forum: C Programming
    Replies:
    13
    Views:
    528
    Antoninus Twink
    Feb 2, 2010
  4. WARNING! Prosoftstore.com is a SCAM! WARNING!

    , Jul 8, 2007, in forum: ASP .Net Web Services
    Replies:
    0
    Views:
    319
  5. Julian Mehnle
    Replies:
    17
    Views:
    877
    Julian Mehnle
    May 18, 2006
Loading...

Share This Page