Re: Initialization

Discussion in 'C Programming' started by Ian Collins, Jan 24, 2013.

  1. Ian Collins

    Ian Collins Guest

    Russell Shaw wrote:
    > Hi,
    > In gcc-4.7 C99, this gets accepted in a block scope:
    >
    > static int a = 1;
    >
    >
    > ISO/IEC 9899:201x 6.7.8p5 says:
    >
    > If the declaration of an identifier has block scope, and the identifier has
    > external or internal linkage, the declaration shall have no initializer for the
    > identifier.


    My reading is

    static int a = 1;

    is a definition, covered by 6.7.8 p4.

    --
    Ian Collins
    Ian Collins, Jan 24, 2013
    #1
    1. Advertising

  2. Ian Collins <> writes:

    > Russell Shaw wrote:
    >> Hi,
    >> In gcc-4.7 C99, this gets accepted in a block scope:
    >>
    >> static int a = 1;
    >>
    >>
    >> ISO/IEC 9899:201x 6.7.8p5 says:


    I'm getting confused by the numbering! The document with internal title
    "ISO/IEC 9899:201x" is likely to be the draft of the 2011 standard often
    called "n1570.pdf" but in that document 6.7.8 is about type definitions
    (and p4 and p5 are examples).

    You seem to be citing ISO/IEC 9899:1999. At least in the draft called
    n1256.pdf 6.7.8 is indeed about initialisation and p5 is as you quote it.

    >> If the declaration of an identifier has block scope, and the
    >> identifier has external or internal linkage, the declaration shall
    >> have no initializer for the identifier.

    >
    > My reading is
    >
    > static int a = 1;
    >
    > is a definition, covered by 6.7.8 p4.


    Yes it is, but it does not explain Russell's confusion. For the benefit
    of the thread, p4 says:

    "All the expressions in an initializer for an object that has static
    storage duration shall be constant expressions or string literals."

    Yes, this is an object with static storage duration so the initializer
    (if it is permitted to have one) must be a constant expression. Russell
    is wondering why the initializer is permitted at all because he thinks
    it is (quite understandably) a declaration of an identifier with
    internal linkage to which his p5 would apply. In fact 'a' has no
    linkage as I pointed out in another reply.

    --
    Ben.
    Ben Bacarisse, Jan 24, 2013
    #2
    1. Advertising

  3. Ian Collins

    Ian Collins Guest

    Ben Bacarisse wrote:
    > Ian Collins <> writes:
    >
    >> Russell Shaw wrote:
    >>> Hi,
    >>> In gcc-4.7 C99, this gets accepted in a block scope:
    >>>
    >>> static int a = 1;
    >>>
    >>>
    >>> ISO/IEC 9899:201x 6.7.8p5 says:

    >
    > I'm getting confused by the numbering! The document with internal title
    > "ISO/IEC 9899:201x" is likely to be the draft of the 2011 standard often
    > called "n1570.pdf" but in that document 6.7.8 is about type definitions
    > (and p4 and p5 are examples).
    >
    > You seem to be citing ISO/IEC 9899:1999. At least in the draft called
    > n1256.pdf 6.7.8 is indeed about initialisation and p5 is as you quote it.
    >
    >>> If the declaration of an identifier has block scope, and the
    >>> identifier has external or internal linkage, the declaration shall
    >>> have no initializer for the identifier.

    >>
    >> My reading is
    >>
    >> static int a = 1;
    >>
    >> is a definition, covered by 6.7.8 p4.

    >
    > Yes it is, but it does not explain Russell's confusion. For the benefit
    > of the thread, p4 says:
    >
    > "All the expressions in an initializer for an object that has static
    > storage duration shall be constant expressions or string literals."
    >
    > Yes, this is an object with static storage duration so the initializer
    > (if it is permitted to have one) must be a constant expression. Russell
    > is wondering why the initializer is permitted at all because he thinks
    > it is (quite understandably) a declaration of an identifier with
    > internal linkage to which his p5 would apply. In fact 'a' has no
    > linkage as I pointed out in another reply.


    I realised that when I read your reply. I forgot to stand on my head
    while reading the standard...

    --
    Ian Collins
    Ian Collins, Jan 24, 2013
    #3
  4. Ian Collins

    James Kuyper Guest

    On 01/24/2013 03:47 AM, Russell Shaw wrote:
    > On 24/01/13 14:00, Ben Bacarisse wrote:
    >> Ian Collins<> writes:
    >>
    >>> Russell Shaw wrote:
    >>>> Hi,
    >>>> In gcc-4.7 C99, this gets accepted in a block scope:
    >>>>
    >>>> static int a = 1;
    >>>>
    >>>>
    >>>> ISO/IEC 9899:201x 6.7.8p5 says:

    >>
    >> I'm getting confused by the numbering! The document with internal title
    >> "ISO/IEC 9899:201x" is likely to be the draft of the 2011 standard often
    >> called "n1570.pdf" but in that document 6.7.8 is about type definitions
    >> (and p4 and p5 are examples).
    >>
    >> You seem to be citing ISO/IEC 9899:1999. At least in the draft called
    >> n1256.pdf 6.7.8 is indeed about initialisation and p5 is as you quote it.

    >
    > Hi,
    > I noticed later i should quote the full header from the pdf:
    >
    > WG14/N1336 Committee Draft -- August 11, 2008 ISO/IEC 9899:201x
    >
    >>>> If the declaration of an identifier has block scope, and the
    >>>> identifier has external or internal linkage, the declaration shall
    >>>> have no initializer for the identifier.
    >>>
    >>> My reading is
    >>>
    >>> static int a = 1;
    >>>
    >>> is a definition, covered by 6.7.8 p4.

    >>
    >> Yes it is, but it does not explain Russell's confusion. For the benefit
    >> of the thread, p4 says:
    >>
    >> "All the expressions in an initializer for an object that has static
    >> storage duration shall be constant expressions or string literals."
    >>
    >> Yes, this is an object with static storage duration so the initializer
    >> (if it is permitted to have one) must be a constant expression. Russell
    >> is wondering why the initializer is permitted at all because he thinks
    >> it is (quite understandably) a declaration of an identifier with
    >> internal linkage to which his p5 would apply. In fact 'a' has no
    >> linkage as I pointed out in another reply.

    >
    > Despite reading the standard quite a few times, i did not realize that a
    > "static" identifier (such as in a block scope) is deemed as having no "linkage".


    'static' has several almost completely unrelated meanings. When it
    appears on a declaration with file scope, it means "internal linkage"
    (6.2.2p3). Personally , I think they should have used 'intern' for that
    purpose, making it parallel with 'extern'. As a storage space specifier
    it means "static storage duration" (6.2.4p3). It's not the 'static' that
    means "no linkage" - it's the fact that 'a' was declared with block
    scope, and was not declared 'extern'.

    As of C99, static has yet a third completely different meaning when a
    function parameter of pointer type is declared as if it were actually an
    array, and has 'static' in the leading dimension of that array. (6.7.6.3p7)

    > It makes more sense now, because linkage means the connection between multiple
    > declarations involving the same name, but a block scope can't have multiple
    > declaration thingies (static definitions) of the same name.
    >
    >
    > The connection between "linkage" and storage duration is not helped by
    > vague/meaningless statements like 6.7 p6:
    >
    >
    > "The declaration specifiers consist of a sequence of specifiers that indicate
    > the linkage, storage duration, and part of the type of the entities that the
    > declarators denote."


    That's not meaningless, and it's vague only insofar as the the list of
    specifiers that it's referring to is specified elsewhere (6.7p1), and
    their meanings are all explained elsewhere (6.7.1-6.7.5). This is just a
    summary statement leading into those detailed explanations. The fact
    that some of those meanings depend upon the scope of the declaration is
    one of the details covered elsewhere (6.2).

    > or 6.7 p7: "If an identifier for an object is declared with no linkage, ..."
    >
    >
    > as if to say that "linkage" is specifically set by a specifier (such as
    > "static"). In reality, an internal linkage is set by both the "static" duration
    > specifier *and* the context (inside or outside a function), ...


    No, that wording doesn't imply that the linkage is uniquely determined
    by the declaration specifiers. An identifier for an object has no
    linkage if it is a function parameter or if you declare it with block
    scope without the 'extern' keyword (6.2.2p6). There's nothing in the
    quoted words of 6.7p7 which is inconsistent with the fact that both the
    scope and the absence of certain specifiers have a part to play in
    determining whether those words apply.

    > ... and a file-scope
    > declaration with "extern" can end up having internal linkage if a later "static"
    > definition of the identifier is found in that file.


    The words you quote from 6.7p7 can never apply to a file scope
    declaration; all such declarations have either internal or external linkage.
    --
    James Kuyper
    James Kuyper, Jan 24, 2013
    #4
  5. Russell Shaw <rjshawN_o@s_pam.netspace.net.au> writes:
    [...]
    > I noticed later i should quote the full header from the pdf:
    >
    > WG14/N1336 Committee Draft -- August 11, 2008 ISO/IEC 9899:201x


    That draft has been superseded by later drafts.

    The best draft for C99 in N1256; it consists of the C99 standard with
    the three Technical Corrigenda merged into it.

    The best draft for C11 in N1570. I'm not aware of any differences
    between it and the final published standard -- including an error
    corrected in a Technical Corrigendum. (The TC says that the value of
    __STDC_VERSION__, and of the optionally defined __STDC_LIB_EXT1__, is
    201112L).

    > Rationale for International Standard-- Programming Languages-- C
    > Revision 5.10 April-2003


    References:
    http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf
    http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf
    http://www.open-std.org/jtc1/sc22/wg14/www/C99RationaleV5.10.pdf

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Working, but not speaking, for JetHead Development, Inc.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Jan 24, 2013
    #5
  6. Ian Collins

    James Kuyper Guest

    On 01/25/2013 10:27 PM, Russell Shaw wrote:
    > On 24/01/13 14:00, Ben Bacarisse wrote:
    >> Ian Collins<> writes:
    >>
    >>> Russell Shaw wrote:

    ....
    >>>> If the declaration of an identifier has block scope, and the identifier
    >>>> has external or internal linkage, the declaration shall have no
    >>>> initializer for the identifier.
    >>>
    >>> My reading is
    >>>
    >>> static int a = 1;

    ....
    >> is permitted to have one) must be a constant expression. Russell is wondering
    >> why the initializer is permitted at all because he thinks it is (quite
    >> understandably) a declaration of an identifier with internal linkage to which
    >> his p5 would apply. In fact 'a' has no linkage as I pointed out in another
    >> reply.

    >
    > Hi,
    > How does one declare an identifier in block scope with internal linkage?


    You can't. "The following identifiers have no linkage: an identifier
    declared to be anything other than an object or a function; an
    identifier declared to be a function parameter; a block scope identifier
    for an object declared without the storage-class specifier extern."
    (6.2.2p6). Since the 'extern' keyword gives an identifier external
    linkage, internal linkage isn't an available option for block scope
    identifiers. If you want an identifier to have internal linkage, you
    have to move it to file scope, and declare it static.

    --
    James Kuyper
    James Kuyper, Jan 26, 2013
    #6
  7. Ian Collins

    James Kuyper Guest

    On 01/25/2013 10:36 PM, Russell Shaw wrote:
    ....
    > How does one declare an identifier in block scope with internal linkage?
    >
    > I assume one would put an extern declaration in the function, and have a static
    > definition preceding that function in file scope.


    You're right - that would work. I missed that. However, in that case
    your block scope identifier will identify the same thing as the file
    scope identifier with the same spelling, which would otherwise have been
    visible anyway within the scope of the block scope declaration. It's not
    clear to me that there's any good reason for writing such a declaration.
    --
    James Kuyper
    James Kuyper, Jan 26, 2013
    #7
  8. Ian Collins

    Philip Lantz Guest

    James Kuyper wrote:
    > Russell Shaw wrote:
    > > How does one declare an identifier in block scope with internal linkage?
    > >
    > > I assume one would put an extern declaration in the function, and have a
    > > static definition preceding that function in file scope.

    >
    > You're right - that would work. I missed that. However, in that case
    > your block scope identifier will identify the same thing as the file
    > scope identifier with the same spelling, which would otherwise have been
    > visible anyway within the scope of the block scope declaration. It's not
    > clear to me that there's any good reason for writing such a declaration.


    Agreed that there's no good reason, but I think the following code shows
    a case where the declaration would actually have an effect:

    static int x;

    void f()
    {
    int x;

    {
    extern int x;
    x = 1;
    }
    }
    Philip Lantz, Jan 26, 2013
    #8
  9. Russell Shaw <rjshawN_o@s_pam.netspace.net.au> writes:
    > On 25/01/13 03:13, Keith Thompson wrote:
    >> Russell Shaw<rjshawN_o@s_pam.netspace.net.au> writes:
    >> [...]
    >>> I noticed later i should quote the full header from the pdf:
    >>>
    >>> WG14/N1336 Committee Draft -- August 11, 2008 ISO/IEC 9899:201x

    >>
    >> That draft has been superseded by later drafts.
    >>
    >> The best draft for C99 in N1256; it consists of the C99 standard with
    >> the three Technical Corrigenda merged into it.
    >>
    >> The best draft for C11 in N1570. I'm not aware of any differences
    >> between it and the final published standard -- including an error
    >> corrected in a Technical Corrigendum. (The TC says that the value of
    >> __STDC_VERSION__, and of the optionally defined __STDC_LIB_EXT1__, is
    >> 201112L).
    >>
    >>> Rationale for International Standard-- Programming Languages-- C
    >>> Revision 5.10 April-2003

    >>
    >> References:
    >> http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf
    >> http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf
    >> http://www.open-std.org/jtc1/sc22/wg14/www/C99RationaleV5.10.pdf

    >
    > Hi,
    > Where can i find Technical Corrigenda 3 ?
    >
    > I ordered:
    > <http://www.amazon.com/Standard-Incorporating-Technical-Corrigendum/dp/0470845732/ref=sr_1_1?s=books&ie=UTF8&qid=1359176334&sr=1-1&keywords=The+C+Standard%3A+Incorporating+Technical+Corrigendum>
    >
    > a while ago, but annoyingly it only has TC1.
    >
    > The http://www.iso.org/ web site has withdrawn ISO/IEC 9899:1999 and ISO/IEC
    > 9899:1999/Cor 1/2/3


    Go to webstore.ansi.org and search for "9899". All three C99 TCs, and
    the one C11 TC, are available at no charge (but pay attention to the
    licensing terms).

    You probably don't really *need* the C99 Technical Corrigenda if you
    have a copy of N1256.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Working, but not speaking, for JetHead Development, Inc.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Jan 26, 2013
    #9
    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. JKop
    Replies:
    10
    Views:
    923
  2. Matthias Kaeppler
    Replies:
    2
    Views:
    426
    Victor Bazarov
    Jul 18, 2005
  3. Replies:
    6
    Views:
    451
    Ron Natalie
    Dec 11, 2005
  4. toton
    Replies:
    5
    Views:
    918
    Victor Bazarov
    Sep 28, 2006
  5. Jess
    Replies:
    23
    Views:
    909
Loading...

Share This Page