Re: extern typedef struct

Discussion in 'C Programming' started by BruceS, May 18, 2010.

  1. BruceS

    BruceS Guest

    On May 18, 6:41 am, Richard Heathfield <> wrote:
    > Jeff wrote:

    <snip>
    > > obj.h ===============
    > > #ifndef  __object_h

    >
    > Almost all identifiers with leading underscores are reserved for the
    > implementation. The (slightly over-restrictive, but very easy to
    > remember) rule of thumb is: don't use 'em.
    >
    > If you must have underscore decorations, use trailers, not leaders:
    >
    > #ifndef object_h__
    > #define object_h__


    I've meant to ask about this one before. I've picked up a (probably
    bad) habit of doing as above, from an employer where that was
    "standard". Do these count as identifiers in the restricted space,
    even though they're macros?
     
    BruceS, May 18, 2010
    #1
    1. Advertising

  2. BruceS

    Ben Pfaff Guest

    BruceS <> writes:

    > On May 18, 6:41 am, Richard Heathfield <> wrote:
    >> Jeff wrote:
    >> If you must have underscore decorations, use trailers, not leaders:
    >>
    >> #ifndef object_h__
    >> #define object_h__

    >
    > I've meant to ask about this one before. I've picked up a (probably
    > bad) habit of doing as above, from an employer where that was
    > "standard". Do these count as identifiers in the restricted space,
    > even though they're macros?


    They are not reserved by C, but they are reserved by C++. From
    C++98:

    17.4.3.1.2 Global names [lib.global.names]

    1 Certain sets of names and function signatures are always
    reserved to the implementation:

    - Each name that contains a double underscore (__) or begins
    with an underscore followed by an upper- case letter
    (2.11) is reserved to the implementation for any use.

    It's up to you whether to care about that, of course.
    --
    "It would be a much better example of undefined behavior
    if the behavior were undefined."
    --Michael Rubenstein
     
    Ben Pfaff, May 18, 2010
    #2
    1. Advertising

  3. BruceS

    BruceS Guest

    On May 18, 1:49 pm, Ben Pfaff <> wrote:
    > BruceS <> writes:
    > > On May 18, 6:41 am, Richard Heathfield <> wrote:
    > >> Jeff wrote:
    > >> If you must have underscore decorations, use trailers, not leaders:

    >
    > >> #ifndef object_h__
    > >> #define object_h__

    >
    > > I've meant to ask about this one before.  I've picked up a (probably
    > > bad) habit of doing as above, from an employer where that was
    > > "standard".  Do these count as identifiers in the restricted space,
    > > even though they're macros?

    >
    > They are not reserved by C, but they are reserved by C++.  From
    > C++98:
    >
    >      17.4.3.1.2 Global names [lib.global.names]
    >
    >      1 Certain sets of names and function signatures are always
    >        reserved to the implementation:
    >
    >        - Each name that contains a double underscore (__) or begins
    >          with an underscore followed by an upper- case letter
    >          (2.11) is reserved to the implementation for any use.
    >
    > It's up to you whether to care about that, of course.


    No, I can't say I care about the restrictions in C++. I was just
    concerned about 7.1.3 Reserved identifiers, including "All identifiers
    that begin with an underscore and either an uppercase letter or
    another underscore are always reserved for any use." This would
    include the above usage if they count as identifiers. Now I look at
    6.10.3 Macro replacement, item 2 "An identifier currently defined as a
    macro...", and it looks more conclusive. Macros count as identifiers,
    and identifiers such as __object_h are reserved. Am I missing
    something else? It wouldn't be the first time I'd misinterpreted part
    of the Standard.
     
    BruceS, May 18, 2010
    #3
  4. BruceS

    Ben Pfaff Guest

    BruceS <> writes:

    > On May 18, 1:49 pm, Ben Pfaff <> wrote:
    >> BruceS <> writes:
    >> > On May 18, 6:41 am, Richard Heathfield <> wrote:
    >> >> Jeff wrote:
    >> >> If you must have underscore decorations, use trailers, not leaders:

    >>
    >> >> #ifndef object_h__
    >> >> #define object_h__

    >>
    >> > I've meant to ask about this one before.  I've picked up a (probably
    >> > bad) habit of doing as above, from an employer where that was
    >> > "standard".  Do these count as identifiers in the restricted space,
    >> > even though they're macros?

    >>
    >> They are not reserved by C, but they are reserved by C++.  From
    >> C++98:
    >> [...]
    >> It's up to you whether to care about that, of course.

    >
    > No, I can't say I care about the restrictions in C++. I was just
    > concerned about 7.1.3 Reserved identifiers, including "All identifiers
    > that begin with an underscore and either an uppercase letter or
    > another underscore are always reserved for any use." This would
    > include the above usage if they count as identifiers.


    No, this clause in 7.1.3 doesn't reserve object_h__, because
    object_h__ does not begin with an underscore.

    > Now I look at 6.10.3 Macro replacement, item 2 "An identifier
    > currently defined as a macro...", and it looks more conclusive.
    > Macros count as identifiers, and identifiers such as __object_h
    > are reserved. Am I missing something else? It wouldn't be the
    > first time I'd misinterpreted part of the Standard.


    __object_h is reserved because it begins with two underscores.
    --
    char a[]="\n .CJacehknorstu";int putchar(int);int main(void){unsigned long b[]
    ={0x67dffdff,0x9aa9aa6a,0xa77ffda9,0x7da6aa6a,0xa67f6aaa,0xaa9aa9f6,0x11f6},*p
    =b,i=24;for(;p+=!*p;*p/=4)switch(0[p]&3)case 0:{return 0;for(p--;i--;i--)case+
    2:{i++;if(i)break;else default:continue;if(0)case 1:putchar(a[i&15]);break;}}}
     
    Ben Pfaff, May 18, 2010
    #4
  5. BruceS <> writes:
    > On May 18, 1:49 pm, Ben Pfaff <> wrote:
    >> BruceS <> writes:
    >> > On May 18, 6:41 am, Richard Heathfield <> wrote:
    >> >> Jeff wrote:
    >> >> If you must have underscore decorations, use trailers, not leaders:

    >>
    >> >> #ifndef object_h__
    >> >> #define object_h__

    >>
    >> > I've meant to ask about this one before.  I've picked up a (probably
    >> > bad) habit of doing as above, from an employer where that was
    >> > "standard".  Do these count as identifiers in the restricted space,
    >> > even though they're macros?

    >>
    >> They are not reserved by C, but they are reserved by C++.  From
    >> C++98:
    >>
    >>      17.4.3.1.2 Global names [lib.global.names]
    >>
    >>      1 Certain sets of names and function signatures are always
    >>        reserved to the implementation:
    >>
    >>        - Each name that contains a double underscore (__) or begins
    >>          with an underscore followed by an upper- case letter
    >>          (2.11) is reserved to the implementation for any use.
    >>
    >> It's up to you whether to care about that, of course.

    >
    > No, I can't say I care about the restrictions in C++. I was just
    > concerned about 7.1.3 Reserved identifiers, including "All identifiers
    > that begin with an underscore and either an uppercase letter or
    > another underscore are always reserved for any use." This would
    > include the above usage if they count as identifiers. Now I look at
    > 6.10.3 Macro replacement, item 2 "An identifier currently defined as a
    > macro...", and it looks more conclusive. Macros count as identifiers,
    > and identifiers such as __object_h are reserved. Am I missing
    > something else? It wouldn't be the first time I'd misinterpreted part
    > of the Standard.


    No, you're not missing anything.

    In C, all identifiers starting with either a double underscore or an
    underscore followed by an uppercase letter are reserved for all purposes
    (that includes macros). You should never declare such an identifier
    yourself. For example, the implementation might have declared it as a
    macro. Redefining it as a macro might break the implementation;
    defining it as anything else might break your declaration. You're very
    likely to get away with it in most cases (if your identifier doesn't
    happen to collide with one used by the implementation), but you
    shouldn't try. __FOO might work just fine today, but break with the
    next release of your compiler.

    Identifers starting with an underscore followed by something other than
    a second underscore or an uppercase letter are reserved in fewer
    contexts, but you should still avoid them (it's simpler to remember to
    avoid leading underscores than to remember the odd cases that are
    permitted).

    (C++ additionally reserves identifiers with double underscores; this
    does not apply to C, but if you want to avoid double underscores
    anyway I certainly won't criticize you for it.)

    Trailing underscores are harmless. (In C++, single trailing underscores
    are harmless.) And they're not commonly used, which makes for a handy
    convention for specialized purposes.

    So this:

    #ifdef object_h_
    #define object_h_
    /* ... */
    #endif

    is ok. Another convention I've seen is to use an uppercase name with a
    leading H_:

    #ifdef H_OBJECT
    #define H_OBJECT
    /* ... */
    #endif

    The H_ prefix avoids accidentally using an identifier starting with 'E'.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, May 18, 2010
    #5
  6. BruceS

    BruceS Guest

    On May 18, 3:20 pm, Ben Pfaff <> wrote:
    > BruceS <> writes:
    > > On May 18, 1:49 pm, Ben Pfaff <> wrote:
    > >> BruceS <> writes:
    > >> > On May 18, 6:41 am, Richard Heathfield <> wrote:
    > >> >> Jeff wrote:
    > >> >> If you must have underscore decorations, use trailers, not leaders:

    >
    > >> >> #ifndef object_h__
    > >> >> #define object_h__

    >
    > >> > I've meant to ask about this one before.  I've picked up a (probably
    > >> > bad) habit of doing as above, from an employer where that was
    > >> > "standard".  Do these count as identifiers in the restricted space,
    > >> > even though they're macros?

    >
    > >> They are not reserved by C, but they are reserved by C++.  From
    > >> C++98:
    > >> [...]
    > >> It's up to you whether to care about that, of course.

    >
    > > No, I can't say I care about the restrictions in C++.  I was just
    > > concerned about 7.1.3 Reserved identifiers, including "All identifiers
    > > that begin with an underscore and either an uppercase letter or
    > > another underscore are always reserved for any use."  This would
    > > include the above usage if they count as identifiers.  

    >
    > No, this clause in 7.1.3 doesn't reserve object_h__, because
    > object_h__ does not begin with an underscore.


    Thanks, Ben. Sorry for the confusion; I was referring to the original
    version, from Jeff (__object_h), not the corrected version from
    Richard. I think there was some snippage of context in there.
     
    BruceS, May 19, 2010
    #6
  7. BruceS

    BruceS Guest

    On May 18, 4:50 pm, Keith Thompson <> wrote:
    <snip>
    > In C, all identifiers starting with either a double underscore or an
    > underscore followed by an uppercase letter are reserved for all purposes
    > (that includes macros).  You should never declare such an identifier
    > yourself.  For example, the implementation might have declared it as a
    > macro.  Redefining it as a macro might break the implementation;
    > defining it as anything else might break your declaration.  You're very
    > likely to get away with it in most cases (if your identifier doesn't
    > happen to collide with one used by the implementation), but you
    > shouldn't try.  __FOO might work just fine today, but break with the
    > next release of your compiler.
    >
    > Identifers starting with an underscore followed by something other than
    > a second underscore or an uppercase letter are reserved in fewer
    > contexts, but you should still avoid them (it's simpler to remember to
    > avoid leading underscores than to remember the odd cases that are
    > permitted).
    >
    > (C++ additionally reserves identifiers with double underscores; this
    > does not apply to C, but if you want to avoid double underscores
    > anyway I certainly won't criticize you for it.)
    >
    > Trailing underscores are harmless.  (In C++, single trailing underscores
    > are harmless.)  And they're not commonly used, which makes for a handy
    > convention for specialized purposes.
    >
    > So this:
    >
    > #ifdef object_h_
    > #define object_h_
    > /* ... */
    > #endif
    >
    > is ok.  Another convention I've seen is to use an uppercase name with a
    > leading H_:
    >
    > #ifdef H_OBJECT
    > #define H_OBJECT
    > /* ... */
    > #endif
    >
    > The H_ prefix avoids accidentally using an identifier starting with 'E'.


    Thanks, Keith, that confirms it nicely. It looks like that was indeed
    a bad practice, and I'll amend it. I think I'll go with the
    myheader_h_ approach. That seems extremely unlikely to collide with
    any other identifiers, and is every bit as clear as __myheader_h.
     
    BruceS, May 19, 2010
    #7
    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. DanielEKFA
    Replies:
    8
    Views:
    626
    DanielEKFA
    May 16, 2005
  2. Steven T. Hatton
    Replies:
    2
    Views:
    684
  3. Dirk Bruere at NeoPax

    How to declare extern typedef struct?

    Dirk Bruere at NeoPax, Dec 6, 2008, in forum: C Programming
    Replies:
    4
    Views:
    11,794
    Dirk Bruere at NeoPax
    Dec 7, 2008
  4. Jens Thoms Toerring

    Re: extern typedef struct

    Jens Thoms Toerring, May 18, 2010, in forum: C Programming
    Replies:
    0
    Views:
    643
    Jens Thoms Toerring
    May 18, 2010
  5. Seebs

    Re: extern typedef struct

    Seebs, May 18, 2010, in forum: C Programming
    Replies:
    3
    Views:
    579
    Jens Thoms Toerring
    May 18, 2010
Loading...

Share This Page