Re: Linkage

Discussion in 'C Programming' started by BartC, Jan 26, 2013.

  1. BartC

    BartC Guest

    "Russell Shaw" <rjshawN_o@s_pam.netspace.net.au> wrote in message
    news:...

    > extern int a;
    > static int a;
    >
    > I get: error: static declaration of 'a' follows non-static declaration
    >
    >
    > In WG14/N1256, 6.2.7 p4 seems to say this should not be an error.


    Are you debugging an actual program, or the C standard?!

    At file-scope, "extern int a" might be compatible with an "int a" in the
    same module, but not with "static int a" (I'm sure you know the meanings of
    all these). So the error message is justified.

    --
    Bartc
     
    BartC, Jan 26, 2013
    #1
    1. Advertising

  2. BartC

    Tim Rentsch Guest

    "BartC" <> writes:

    > "Russell Shaw" <rjshawN_o@s_pam.netspace.net.au> wrote in message
    > news:...
    >
    >> extern int a;
    >> static int a;
    >>
    >> I get: error: static declaration of 'a' follows non-static declaration
    >>
    >>
    >> In WG14/N1256, 6.2.7 p4 seems to say this should not be an error.

    >
    > Are you debugging an actual program, or the C standard?!
    >
    > At file-scope, "extern int a" might be compatible with an "int
    > a" in the same module, but not with "static int a" (I'm sure
    > you know the meanings of all these). So the error message is
    > justified.


    If you consult 6.2.2 p4 you will see that there is more to
    the story than complete non-compatibility.
     
    Tim Rentsch, Jan 26, 2013
    #2
    1. Advertising

  3. BartC

    James Kuyper Guest

    On 01/26/2013 10:14 AM, BartC wrote:
    > "Russell Shaw" <rjshawN_o@s_pam.netspace.net.au> wrote in message
    > news:...
    >
    >> extern int a;
    >> static int a;
    >>
    >> I get: error: static declaration of 'a' follows non-static declaration
    >>
    >>
    >> In WG14/N1256, 6.2.7 p4 seems to say this should not be an error.

    >
    > Are you debugging an actual program, or the C standard?!
    >
    > At file-scope, "extern int a" might be compatible with an "int a" in the
    > same module, but not with "static int a" (I'm sure you know the meanings of
    > all these). So the error message is justified.


    That explanation suggests that the error message would be equally
    justified if the order of the declarations were reversed. See the other
    messages on this thread for the details of why that's wrong.
    --
    James Kuyper
     
    James Kuyper, Jan 26, 2013
    #3
  4. BartC

    BartC Guest

    "Tim Rentsch" <> wrote in message
    news:...
    > "BartC" <> writes:
    >
    >> "Russell Shaw" <rjshawN_o@s_pam.netspace.net.au> wrote in message
    >> news:...
    >>
    >>> extern int a;
    >>> static int a;
    >>>
    >>> I get: error: static declaration of 'a' follows non-static declaration
    >>>
    >>>
    >>> In WG14/N1256, 6.2.7 p4 seems to say this should not be an error.

    >>
    >> Are you debugging an actual program, or the C standard?!
    >>
    >> At file-scope, "extern int a" might be compatible with an "int
    >> a" in the same module, but not with "static int a" (I'm sure
    >> you know the meanings of all these). So the error message is
    >> justified.

    >
    > If you consult 6.2.2 p4 you will see that there is more to
    > the story than complete non-compatibility.


    But then 6.2.2 p7 appears to contradict that.

    --
    Bartc
     
    BartC, Jan 26, 2013
    #4
  5. BartC

    James Kuyper Guest

    On 01/26/2013 01:21 PM, BartC wrote:
    >
    >
    > "Tim Rentsch" <> wrote in message
    > news:...
    >> "BartC" <> writes:
    >>
    >>> "Russell Shaw" <rjshawN_o@s_pam.netspace.net.au> wrote in message
    >>> news:...
    >>>
    >>>> extern int a;
    >>>> static int a;
    >>>>
    >>>> I get: error: static declaration of 'a' follows non-static declaration
    >>>>
    >>>>
    >>>> In WG14/N1256, 6.2.7 p4 seems to say this should not be an error.
    >>>
    >>> Are you debugging an actual program, or the C standard?!
    >>>
    >>> At file-scope, "extern int a" might be compatible with an "int
    >>> a" in the same module, but not with "static int a" (I'm sure
    >>> you know the meanings of all these). So the error message is
    >>> justified.

    >>
    >> If you consult 6.2.2 p4 you will see that there is more to
    >> the story than complete non-compatibility.

    >
    > But then 6.2.2 p7 appears to contradict that.


    Only because the extern declaration occurs first. If the order were
    reversed, then because of 6.2.2p4, both declarations would give it
    internal linkage, and 6.2.2p7 wouldn't apply.
    If it was simply a matter of the two declarations being incompatible,
    the relative order of the declarations wouldn't matter.
    --
    James Kuyper
     
    James Kuyper, Jan 26, 2013
    #5
  6. BartC

    BartC Guest

    "James Kuyper" <> wrote in message
    news:ke19dv$m45$...
    > On 01/26/2013 01:21 PM, BartC wrote:


    >> "Tim Rentsch" <> wrote in message


    >>> If you consult 6.2.2 p4 you will see that there is more to
    >>> the story than complete non-compatibility.

    >>
    >> But then 6.2.2 p7 appears to contradict that.

    >
    > Only because the extern declaration occurs first. If the order were
    > reversed, then because of 6.2.2p4, both declarations would give it
    > internal linkage, and 6.2.2p7 wouldn't apply.
    > If it was simply a matter of the two declarations being incompatible,
    > the relative order of the declarations wouldn't matter.


    OK, C declarations are more messed up than I thought. (I knew it was a
    mistake to actually look at the standard!)

    So, a static identifier is static.

    But an extern identifier might also be static, depending on something in the
    source code a thousand lines back, hidden in a 5-deep include file.

    As for identifiers which are not static, and not extern (ie. defined here
    and exported from this module), I've no idea now how they fit into the
    picture. Unless they have to pretend to be extern too. (Then, in the absence
    of one module claiming ownership by initialising the associated object, the
    linker might be kind enough to define it anyway.)

    (I try to impose a simpler model on my function identifiers in C:

    global functions - defined here and exported
    local functions - defined here and only used here
    external functions - defined elsewhere but imported for use here

    And the way I use C, I only need to write global or local function
    definitions; no extern declarations or prototypes are needed.

    Applying the same model for variables is a little trickier, and for those I
    do have to declare global variables twice (as extern, and again as global).
    I understand that behind the scenes, C does unsavoury things such as
    allowing an extern declaration to be followed by a global definition, but I
    try to put that out of my mind. Now it seems it does even more stuff I have
    to steer well clear of...)

    --
    Bartc
     
    BartC, Jan 26, 2013
    #6
  7. BartC

    James Kuyper Guest

    On 01/26/2013 04:59 PM, Richard Damon wrote:
    > On 1/26/13 4:22 PM, BartC wrote:
    >
    >> (I try to impose a simpler model on my function identifiers in C:
    >>
    >> global functions - defined here and exported
    >> local functions - defined here and only used here
    >> external functions - defined elsewhere but imported for use here
    >>
    >> And the way I use C, I only need to write global or local function
    >> definitions; no extern declarations or prototypes are needed.
    >>

    >
    > It is very hard to use a global function from another translation unit
    > without a extern (prototype) definition. (It was allowed in C90 under
    > limited conditions, but becomes a constraint error in C99 and later).


    I think you're confusing function definitions with function
    declarations. A function definition has always been necessary for a
    successful function call. However, in C99, having a function declaration
    visible in the current scope became mandatory - that may be what you're
    thinking about.
    Also, a function declaration doesn't have to be a function prototype.
    Non-prototype function declarations are still supported as of C2011.
    --
    James Kuyper
     
    James Kuyper, Jan 26, 2013
    #7
  8. BartC

    James Kuyper Guest

    On 01/26/2013 04:22 PM, BartC wrote:
    ....
    > As for identifiers which are not static, and not extern (ie. defined here
    > and exported from this module), I've no idea now how they fit into the
    > picture. ...


    Because of the multiple meanings attached to the 'static' keyword by the
    C language, it's best to avoid using 'static' as an adjective all by
    itself. The relevant phrases are "internal linkage", "external linkage",
    and "no linkage", "static storage duration" and "automatic storage
    duration" (there are other storage durations, but they're not likely to
    be relevant in this context).

    Could you describe the category you're talking about in those terms?

    By "not static, and not extern", do you mean identifiers declared
    without using either of those keywords? If so, there's some simple rules:
    If it identifies a function, it has external linkage. If it identifies a
    file scope object it has external linkage and static storage duration.
    If it identifies a block scope object it has no linkage, and automatic
    storage duration. In all other cases, the identifier has no linkage and
    no associated storage, so it therefore has no associated storage duration.

    Or, by "not static, and not extern", do you mean identifiers with
    neither internal nor external linkage? If so, they're an extremely
    diverse group, which means that there's very little that can usefully be
    said about the entire group. They include all struct, union, and enum
    tags and members. They include macro names, statement labels, typedef
    names, function parameter names, and all variables declared with block
    scope and without 'extern'.

    Or, by "not static, and not extern", do you mean identifiers with
    neither static storage duration nor external linkage? That's an even
    larger group, and there's corresponding less that can be usefully said
    about it the entire group.

    > ... Unless they have to pretend to be extern too. (Then, in the absence
    > of one module claiming ownership by initialising the associated object, the
    > linker might be kind enough to define it anyway.)


    The comment about "pretend to be extern" suggests to me that you may be
    referring to identifiers declared without the 'extern' keyword. Some of
    those identifiers do have external linkage - there's nothing "pretend"
    about it, but there is something implicit about it.

    ....
    > And the way I use C, I only need to write global or local function
    > definitions; no extern declarations or prototypes are needed.


    In C, you can avoid writing declarations with external linkage only by
    keeping all of the functions in your program in a single module.
    However, it's entirely normal to not have any need to write declarations
    using the 'extern' keyword, because functions implicitly have external
    linkage unless specified otherwise.
    --
    James Kuyper
     
    James Kuyper, Jan 26, 2013
    #8
  9. BartC

    BartC Guest

    "Richard Damon" <> wrote in message
    news:LkYMs.356815$1.easynews.com...
    > On 1/26/13 4:22 PM, BartC wrote:


    >> And the way I use C, I only need to write global or local function
    >> definitions; no extern declarations or prototypes are needed.
    >>

    >
    > It is very hard to use a global function from another translation unit
    > without a extern (prototype) definition. (It was allowed in C90 under
    > limited conditions, but becomes a constraint error in C99 and later).


    (The extern declarations are there, but I don't write them myself. My C
    source is pre-processed before compiling, and a file of exported functions,
    and one of local function prototypes, are created, which are then included
    in the right places.

    For this purpose it was simplest to use a keyword or two before each
    function definition to make them easier to pick out (so they will have
    'function' or 'global function' in front). It just makes life much easier!
    And I don't need to keep 6.2.2 in mind all the time either (and before today
    I'd never heard of it).

    I expect development tools such as C IDEs also have plenty of such features
    to make coding simpler.)

    --
    Bartc
     
    BartC, Jan 26, 2013
    #9
  10. BartC

    BartC Guest

    "James Kuyper" <> wrote in message
    news:ke1n9s$b13$...
    > On 01/26/2013 04:22 PM, BartC wrote:
    > ...
    >> As for identifiers which are not static, and not extern (ie. defined here
    >> and exported from this module), I've no idea now how they fit into the
    >> picture. ...

    >
    > Because of the multiple meanings attached to the 'static' keyword by the
    > C language, it's best to avoid using 'static' as an adjective all by
    > itself. The relevant phrases are "internal linkage", "external linkage",
    > and "no linkage", "static storage duration" and "automatic storage
    > duration" (there are other storage durations, but they're not likely to
    > be relevant in this context).
    >
    > Could you describe the category you're talking about in those terms?
    >
    > By "not static, and not extern", do you mean identifiers declared
    > without using either of those keywords?


    > Or, by "not static, and not extern", do you mean identifiers with
    > neither internal nor external linkage? If so, they're an extremely
    > diverse group, which means that there's very little that can usefully be
    > said about the entire group. They include all struct, union, and enum
    > tags and members. They include macro names, statement labels, typedef
    > names, function parameter names, and all variables declared with block
    > scope and without 'extern'.
    >
    > Or, by "not static, and not extern", do you mean identifiers with
    > neither static storage duration nor external linkage? That's an even
    > larger group, and there's corresponding less that can be usefully said
    > about it the entire group.


    Sorry, I thought I was being obvious. But perhaps there is something about
    the terms 'extern' and 'external linkage' as used by C that I'm missing. To
    me, 'external' means something that is imported. What I referred to as
    'static' were things that are neither imported nor exported (ie local). The
    last group, 'not static and not extern', I mean names that are exported.

    Examples showing how my various groups are expressed in normal C (in my
    preprocessed version, I make them more obvious):

    local static int fna(void){}
    exported int fnb(void){}
    imported extern fnb(void);
    or implicit

    So imported, exported, or local. I would guess that C uses 'extern' to mean
    both imported and exported names (fnb and fnc in my table).

    I'm also talking about objects which, when exported or imported, need the
    linker's help to achieve that. Not about structs, unions, enums, macros, or
    typedefs, which can easily shared across modules simply by duplicating their
    definitions in each module (by them appearing in a common header file for
    example).

    --
    Bartc
     
    BartC, Jan 26, 2013
    #10
  11. BartC

    James Kuyper Guest

    On 01/26/2013 06:26 PM, BartC wrote:
    ....
    > Sorry, I thought I was being obvious. But perhaps there is something about
    > the terms 'extern' and 'external linkage' as used by C that I'm missing. To
    > me, 'external' means something that is imported. What I referred to as
    > 'static' were things that are neither imported nor exported (ie local). The
    > last group, 'not static and not extern', I mean names that are exported.


    It would help greatly, if you desire to communicate on this newsgroup
    clearly, to learn the meanings that the C standard assigns to various
    terms; to use those terms with those meanings, where appropriate; and to
    avoid using such terms in ways that conflict with those meanings.

    Of course, terms defined by the C standard might be misleading,
    meaningless or irrelevant when discussing your own personal language;
    but then, this is not really the right place for discussions of that
    language.

    I would guess that your "exported" probably corresponds to "identifiers
    with external linkage defined in the current translation unit", while
    "imported" probably corresponds to "identifiers with external linkage
    defined in other translation units". If so, then taken literally,
    "things that are neither imported nor exported" would include all
    identifiers with internal linkage, plus all identifiers with no linkage.
    However, I suspect that your term "things" implies a restriction that
    might exclude most of the identifiers that have no linkage, such as
    struct tags. It's not clear to me whether "things", as you use the term,
    includes objects with automatic storage duration.
    --
    James Kuyper
     
    James Kuyper, Jan 27, 2013
    #11
  12. BartC

    BartC Guest

    "James Kuyper" <> wrote in message
    news:ke23vl$akl$...
    > On 01/26/2013 06:26 PM, BartC wrote:
    > ...
    >> Sorry, I thought I was being obvious. But perhaps there is something
    >> about
    >> the terms 'extern' and 'external linkage' as used by C that I'm missing.
    >> To
    >> me, 'external' means something that is imported. What I referred to as
    >> 'static' were things that are neither imported nor exported (ie local).
    >> The
    >> last group, 'not static and not extern', I mean names that are exported.

    >
    > It would help greatly, if you desire to communicate on this newsgroup
    > clearly, to learn the meanings that the C standard assigns to various
    > terms; to use those terms with those meanings, where appropriate; and to
    > avoid using such terms in ways that conflict with those meanings.


    The thread is about trying to decipher what the Standard says about
    'linkage'. While the terms it uses have to be spelled out (eg 'static'),
    mine are self-explanatory (eg. 'local').

    > Of course, terms defined by the C standard might be misleading,
    > meaningless or irrelevant when discussing your own personal language;
    > but then, this is not really the right place for discussions of that
    > language.


    It's not about a personal language. The model I described for the 'linkage'
    of identifiers is fairly universal, and is probably exactly what a lot of C
    programmers want to achieve. Thinking along those lines can make it easier
    to program in C.

    (For example, perhaps many like me never realised for a long time that the
    default 'linkage' of file-scope names is to export them. That's the opposite
    of what might be expected! For that reason, I started off by prefixing most
    such names, with the empty macro 'global', to remind me.)

    > I would guess that your "exported" probably corresponds to "identifiers
    > with external linkage defined in the current translation unit", while
    > "imported" probably corresponds to "identifiers with external linkage
    > defined in other translation units".


    Yes. But mine are shorter. Perhaps C needs some snazzier words for them too
    instead of relying on confusing and overloaded terms. But then, they would
    need to accommodate some obscure rules too.

    > If so, then taken literally,
    > "things that are neither imported nor exported" would include all
    > identifiers with internal linkage, plus all identifiers with no linkage.
    > However, I suspect that your term "things" implies a restriction that
    > might exclude most of the identifiers that have no linkage, such as
    > struct tags. It's not clear to me whether "things", as you use the term,
    > includes objects with automatic storage duration.


    It must be obvious that 'linkage' is mainly to do with functions, and to
    a lesser extent with variables**. Any other connotations are not relevant.

    And while in other languages it might apply to other things too, the
    question of importing or exporting a typedef for example isn't really
    meaningful in C.

    [** I'm sure you know what I mean here, without having to give a long
    explanation.]

    --
    Bartc
     
    BartC, Jan 27, 2013
    #12
  13. BartC

    BartC Guest

    "Russell Shaw" <rjshawN_o@s_pam.netspace.net.au> wrote in message
    news:...
    > On 27/01/13 02:14, BartC wrote:
    >> "Russell Shaw" <rjshawN_o@s_pam.netspace.net.au> wrote in message
    >> news:...
    >>
    >>> extern int a;
    >>> static int a;
    >>>
    >>> I get: error: static declaration of 'a' follows non-static declaration
    >>>
    >>>
    >>> In WG14/N1256, 6.2.7 p4 seems to say this should not be an error.

    >>
    >> Are you debugging an actual program, or the C standard?!

    >
    > Debugging a C99 compiler i've been writing. I have to understand every
    > line of the standard. I'll look at C11 some day.


    Good luck.

    (A few times, I've toyed with the mad idea of writing a C front-end to one
    of my projects. But there are just too many quirks, I disagree with many of
    the language decisions, and I don't like reading standards!)

    --
    Bartc
     
    BartC, Jan 27, 2013
    #13
  14. BartC

    BartC Guest

    "Russell Shaw" <rjshawN_o@s_pam.netspace.net.au> wrote in message
    news:...
    > On 27/01/13 22:27, BartC wrote:


    >> The thread is about trying to decipher what the Standard says about
    >> 'linkage'. While the terms it uses have to be spelled out (eg 'static'),
    >> mine are self-explanatory (eg. 'local').

    > ...
    >
    > Useful stuff on linkage starts on P.31 of the Rationale.
    >
    > <http://www.open-std.org/jtc1/sc22/wg14/www/docs/C99RationaleV5.10.pdf>


    A couple of pages further on, it says that pre-C89 the way linkage was
    handled was even more diverse. So what we have now is the simplified
    version...

    --
    Bartc
     
    BartC, Jan 27, 2013
    #14
  15. BartC

    James Kuyper Guest

    On 01/27/2013 06:27 AM, BartC wrote:
    >
    >
    > "James Kuyper" <> wrote in message
    > news:ke23vl$akl$...

    ...
    >> It would help greatly, if you desire to communicate on this newsgroup
    >> clearly, to learn the meanings that the C standard assigns to various
    >> terms; to use those terms with those meanings, where appropriate; and to
    >> avoid using such terms in ways that conflict with those meanings.

    >
    > The thread is about trying to decipher what the Standard says about
    > 'linkage'. While the terms it uses have to be spelled out (eg 'static'),
    > mine are self-explanatory (eg. 'local').


    No, they are not. I've seen plenty of disagreement about the meanings of
    such informal terms. An idea that can be explained using standard
    terminology, should be explained using standard terminology, if you know
    how to do so, in order to reduce the ambiguity. Ideas can also be
    explained in less formal terminology for the benefit of those who don't
    yet know the standard terminology, but the less formal terminology is
    inherently ambiguous and confusing, and the sooner that people learn
    that terminology, the better, if they wish to discuss such topics.

    > (For example, perhaps many like me never realised for a long time that the
    > default 'linkage' of file-scope names is to export them. That's the opposite
    > of what might be expected! For that reason, I started off by prefixing most
    > such names, with the empty macro 'global', to remind me.)


    The default linkage is different for function identifiers and object
    identifiers, and those defaults reflect the linkage that was, in the
    opinion of the designers, the most common case for file scope
    identifiers of that type. I know that, because of those defaults, I
    almost never need to specify the linkage, so I suspect they made a good
    choice. YMMV

    There's so many basic aspects of C that surprise you - it seems like you
    still have a lot to learn about it. I'd recommend not being so
    judgmental about the language until you start getting surprised less
    frequently. The language is far from perfect, but it all fits together
    somewhat better than you seem to think it does, possibly because of the
    aspects of it that you still don't understand properly yet.

    ....
    >> If so, then taken literally,
    >> "things that are neither imported nor exported" would include all
    >> identifiers with internal linkage, plus all identifiers with no linkage.
    >> However, I suspect that your term "things" implies a restriction that
    >> might exclude most of the identifiers that have no linkage, such as
    >> struct tags. It's not clear to me whether "things", as you use the term,
    >> includes objects with automatic storage duration.

    >
    > It must be obvious that 'linkage' is mainly to do with functions, and to
    > a lesser extent with variables**. Any other connotations are not relevant.


    In C, "an identifier declared to be anything other than
    an object or a function" has no linkage, so as far as that goes, it's
    consistent with what you just said. However, some of the identifiers
    that have no linkage also identify objects; specifically, those
    identifiers that identify function parameters or that have block scope
    and were not explicitly declared 'extern'. It's not clear to me whether
    the category you described as "things that are neither imported nor
    exported" was meant to include those identifiers.

    If that category was intended to include them, then it is most
    definitely NOT the case that "they have to pretend to be extern too".

    If they are NOT included in that category, then you don't have to worry
    about that category, it's empty. For one reason or another you've
    excluded every identifier that has "no linkage" according to the C
    standard from that category, even though none of those identifiers are
    either imported or exported. Presumably, therefore, they don't qualify
    as "things", in the sense that you meant that term. It's that kind of
    issue that makes me prefer more precise terminology.

    > [** I'm sure you know what I mean here, without having to give a long
    > explanation.]


    Don't count on it - that's why I want you to learn the C standard's
    terminology, so you can explain what you mean more clearly and precisely.
    --
    James Kuyper
     
    James Kuyper, Jan 27, 2013
    #15
  16. BartC

    BartC Guest

    "James Kuyper" <> wrote in message
    news:ke3m1k$k7n$...
    > On 01/27/2013 06:27 AM, BartC wrote:


    >> (For example, perhaps many like me never realised for a long time that
    >> the
    >> default 'linkage' of file-scope names is to export them. That's the
    >> opposite
    >> of what might be expected!


    > The default linkage is different for function identifiers and object
    > identifiers, and those defaults reflect the linkage that was, in the
    > opinion of the designers, the most common case for file scope
    > identifiers of that type. I know that, because of those defaults, I
    > almost never need to specify the linkage, so I suspect they made a good
    > choice. YMMV


    In my main C project, only 40% of functions need to be exported. In one
    module, less than 1%. While needlessly exporting functions and variables
    *can* be harmless, it can also cause problems; sometimes, problems causing
    mysterious bugs.

    For example, declaring 'int a' in one module, and 'int a' in another,
    thinking they are independent; but they're actually the same variable!

    > There's so many basic aspects of C that surprise you - it seems like you
    > still have a lot to learn about it. I'd recommend not being so
    > judgmental about the language until you start getting surprised less
    > frequently. The language is far from perfect, but it all fits together
    > somewhat better than you seem to think it does, possibly because of the
    > aspects of it that you still don't understand properly yet.


    Yet, I look a more recent language such as Go, and a lot of things in C I've
    had issue with in the past have been tidied up! (But plenty are still
    there...)

    --
    Bartc
     
    BartC, Jan 27, 2013
    #16
  17. BartC

    Philip Lantz Guest

    James Kuyper wrote:
    > BartC wrote:
    > > (For example, perhaps many like me never realised for a long time
    > > that the default 'linkage' of file-scope names is to export them.

    >
    > The default linkage is different for function identifiers and object
    > identifiers....


    int x;
    int y(void);

    at file scope have the same linkage.


    > I know that, because of those defaults, I
    > almost never need to specify the linkage, so I suspect they made a good
    > choice. YMMV


    I'm surprised that you don't find--as Bart and I do--that most file-
    scope identifiers for functions and variables are best declared with
    internal linkage.
     
    Philip Lantz, Jan 27, 2013
    #17
  18. BartC

    Shao Miller Guest

    On 1/27/2013 13:53, Philip Lantz wrote:
    > James Kuyper wrote:
    >> BartC wrote:
    >>> (For example, perhaps many like me never realised for a long time
    >>> that the default 'linkage' of file-scope names is to export them.

    >>
    >> The default linkage is different for function identifiers and object
    >> identifiers....

    >
    > int x;
    > int y(void);
    >
    > at file scope have the same linkage.
    >


    He might've been referring to that 'x' has external linkage but 'y' can
    be influenced by a prior declaration.

    >
    >> I know that, because of those defaults, I
    >> almost never need to specify the linkage, so I suspect they made a good
    >> choice. YMMV

    >
    > I'm surprised that you don't find--as Bart and I do--that most file-
    > scope identifiers for functions and variables are best declared with
    > internal linkage.
    >


    Agreed. Since it's not too much work, I enjoy:

    - File-scope
    - Declarations: Explicit linkage specification
    - Definitions: 'static' for internal linkage, no specifier for
    external linkage

    I find that it's sometimes useful for demonstrative code to omit linkage
    specification, as it can distract from the purpose of the demonstration.

    --
    - Shao Miller
    --
    "Thank you for the kind words; those are the kind of words I like to hear.

    Cheerily," -- Richard Harter
     
    Shao Miller, Jan 27, 2013
    #18
  19. BartC

    BartC Guest

    "Richard Damon" <> wrote in message
    news:LkYMs.356815$1.easynews.com...
    > On 1/26/13 4:22 PM, BartC wrote:
    >
    >> (I try to impose a simpler model on my function identifiers in C:
    >>
    >> global functions - defined here and exported
    >> local functions - defined here and only used here
    >> external functions - defined elsewhere but imported for use here
    >>
    >> And the way I use C, I only need to write global or local function
    >> definitions; no extern declarations or prototypes are needed.
    >>

    >
    > It is very hard to use a global function from another translation unit
    > without a extern (prototype) definition. (It was allowed in C90 under
    > limited conditions, but becomes a constraint error in C99 and later).


    I haven't noticed that it's very hard at all! I find it possible to use
    functions where no definition and no declaration exists; usually it gives a
    link error later on, although it would be more useful sooner, before wasting
    time compiling and optimising a large file.

    But there are also, as I've just found out, problems when a definition does
    exist, but no suitable prototype (in this case due a missing include
    statement). Then no link error is given; you only notice when the program
    crashes (hopefully sooner rather than later) because of a missing parameter
    or wrong type.

    Doubtless there is some switch somewhere or other on my gcc to change this
    behaviour (but it's usually a major undertaking to find out what it might
    be). What's astounding however was that this state of affairs was considered
    acceptable for years.

    --
    Bartc
     
    BartC, Jan 30, 2013
    #19
  20. BartC

    James Kuyper Guest

    On 01/30/2013 04:04 PM, BartC wrote:
    >
    >
    > "Richard Damon" <> wrote in message
    > news:LkYMs.356815$1.easynews.com...
    >> On 1/26/13 4:22 PM, BartC wrote:
    >>
    >>> (I try to impose a simpler model on my function identifiers in C:
    >>>
    >>> global functions - defined here and exported
    >>> local functions - defined here and only used here
    >>> external functions - defined elsewhere but imported for use here
    >>>
    >>> And the way I use C, I only need to write global or local function
    >>> definitions; no extern declarations or prototypes are needed.
    >>>

    >>
    >> It is very hard to use a global function from another translation unit
    >> without a extern (prototype) definition. (It was allowed in C90 under
    >> limited conditions, but becomes a constraint error in C99 and later).

    >
    > I haven't noticed that it's very hard at all! I find it possible to use
    > functions where no definition and no declaration exists; usually it gives a
    > link error later on, although it would be more useful sooner, before wasting
    > time compiling and optimising a large file.


    What Richard meant is unclear, but I would not consider that your
    program has actually used a function until it has been successfully
    executed.

    > But there are also, as I've just found out, problems when a definition does
    > exist, but no suitable prototype (in this case due a missing include
    > statement). Then no link error is given; you only notice when the program
    > crashes (hopefully sooner rather than later) because of a missing parameter
    > or wrong type.


    In C99, calling a function without a declaration in scope is a
    constraint violation (6.5.2.2p1) - you should have gotten at least one
    diagnostic message. Note: the declaration doesn't have to be a function
    prototype.

    In C90, using an otherwise undefined identifier as if it were a
    function's identifier caused it to be treated as if it had been given a
    non-prototyped declaration, with an implicit return type of 'int' - C99
    dropped the "implicit int" rule. The problem you describe is precisely
    why that change was made. Have you been compiling for C90?

    C99 still has related traps for the unwary: non-prototype declarations
    are still allowed for backwards compatibility, and if a call is made to
    a function declared without a prototype, no validity checks are required
    on the arguments for compatibility with the function definition. It's
    not possible for a compiler to perform such checks if the call and the
    definition occur in different translation units.

    This is why non-prototype function declarations should be at least
    obsolescent - but there's an awful lot of legacy code out there that
    depends upon that feature. Also, it's not possible to write a fully
    prototyped declaration of a function that returns a pointer to a
    function of it's own type, or which takes a pointer to such a function
    as an argument. That way leads to infinite recursion, which you can
    currently terminate by, somewhere along the line, using an unprototyped
    declaration.

    Another trap is that if the prototype that's in scope at the point where
    a function is called is incompatible with the definition of the
    function, the behavior is undefined, and there's no way for the compiler
    to detect this problem, either, if they call and the definition occur in
    different translation units.

    > Doubtless there is some switch somewhere or other on my gcc to change this
    > behaviour (but it's usually a major undertaking to find out what it might
    > be). What's astounding however was that this state of affairs was considered
    > acceptable for years.


    -std=c99 -Wall -Wstrict-prototypes -Wmissing-prototypes covers most of
    the possible issues with function prototypes.
     
    James Kuyper, Jan 30, 2013
    #20
    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. Sönke Greve

    TabStrip Control with direct linkage?

    Sönke Greve, Jan 22, 2006, in forum: ASP .Net
    Replies:
    0
    Views:
    357
    Sönke Greve
    Jan 22, 2006
  2. Thomas Dorris

    JNI linkage issue

    Thomas Dorris, Jan 31, 2004, in forum: Java
    Replies:
    2
    Views:
    3,129
    Thomas Dorris
    Feb 2, 2004
  3. Mary
    Replies:
    1
    Views:
    4,039
    Thomas Fritsch
    Oct 11, 2004
  4. Don@NoSpam

    Devious linkage to enter Web site

    Don@NoSpam, Jul 5, 2004, in forum: HTML
    Replies:
    3
    Views:
    494
    brucie
    Jul 5, 2004
  5. Replies:
    1
    Views:
    613
    Michael DOUBEZ
    Sep 12, 2008
Loading...

Share This Page