Re: identifier scope in old-style declarations

Discussion in 'C Programming' started by Huibert Bol, Aug 6, 2008.

  1. Huibert Bol

    Huibert Bol Guest

    Eric Sosman wrote:

    > Thomas Pornin wrote:
    >> Hello,
    >>
    >> with gcc-4.2.3, this does not compile:
    >>
    >> typedef int foo;
    >> int f(foo)
    >> int foo;
    >> {
    >> return foo;
    >> }
    >>
    >> The error message is rather explicit ("old-style parameter declarations
    >> in prototyped function definition"), which means that the compiler, when
    >> encountering the "foo" on the second line, considered it to be a type
    >> name, and not an argument name which would override the global type
    >> definition within the function scope.
    >>
    >> I understand, from a practical point of view, that doing otherwise would
    >> mess the compiler (it would contradict the almost-LALR(1) property of
    >> the C grammer). However, I cannot find in the C standard where such an
    >> override is forbidden. Right now, it seems to me that the construction
    >> is ambiguous.
    >>
    >> Could someone shed some light on this ?

    >
    > Had to hunt for it a little, but I found it. 6.9.1p6: "[...] An
    > identifier declared as a typedef name shall not be redeclared as a
    > parameter. [...]"


    But that's only the case if the declarator includes an _identifier list_, but
    in the example above contains a _parameter type list_; so 6.9.1p5 applies:
    "[...] No declaration list shall follow." which matches the error message
    above.

    - Huibert.
     
    Huibert Bol, Aug 6, 2008
    #1
    1. Advertising

  2. Huibert Bol

    Huibert Bol Guest

    Eric Sosman wrote:

    > For example, how would you describe the error in
    >
    > #include <stdio.h>
    > int man(void) {
    > return puts ("Hello, world!\n") == EOF;
    > }
    >
    > ? (Yes, this is a trick question.)


    It prints an additional newline ;-)

    - Huibert.
     
    Huibert Bol, Aug 6, 2008
    #2
    1. Advertising

  3. "Huibert Bol" <> wrote in message
    news:g7cqut$9qc$...
    > Eric Sosman wrote:
    >
    >> For example, how would you describe the error in
    >>
    >> #include <stdio.h>
    >> int man(void) {
    >> return puts ("Hello, world!\n") == EOF;
    >> }
    >>
    >> ? (Yes, this is a trick question.)

    >
    > It prints an additional newline ;-)


    Doubtful it will print anything...
    it's missing the function called at program startup.
     
    Mark B [Diputsur], Aug 6, 2008
    #3
  4. Huibert Bol

    Huibert Bol Guest

    Mark B. wrote:

    > "Huibert Bol" <> wrote in message
    > news:g7cqut$9qc$...
    >> Eric Sosman wrote:
    >>
    >>> For example, how would you describe the error in
    >>>
    >>> #include <stdio.h>
    >>> int man(void) {
    >>> return puts ("Hello, world!\n") == EOF;
    >>> }
    >>>
    >>> ? (Yes, this is a trick question.)

    >>
    >> It prints an additional newline ;-)

    >
    > Doubtful it will print anything...
    > it's missing the function called at program startup.


    Dûh, Eric never said it was a complete program!

    - Huibert.
     
    Huibert Bol, Aug 6, 2008
    #4
  5. Huibert Bol

    santosh Guest

    Eric Sosman wrote:

    <snip>

    > There's often some ambiguity in pinpointing "the" error in an
    > erroneous source. Fundamentally, all that's really known is that
    > the source is incorrect; diagnosing the nature of its incorrectness
    > involves imagining a plausible correct source and describing the
    > "edit distance" between them. Since there are many, many possible
    > correct sources, there are many possible diagnoses.
    >
    > For example, how would you describe the error in
    >
    > #include <stdio.h>
    > int man(void) {
    > return puts ("Hello, world!\n") == EOF;
    > }
    >
    > ? (Yes, this is a trick question.)


    Well I suppose there would be no error until the last phase of
    translation, which will fail because main is not defined, (and you have
    not told us if the program is freestanding, in which case it would be
    correct, provided the contents of stdio.h and the definition for puts
    are supplied by the user.)
     
    santosh, Aug 6, 2008
    #5
  6. "Huibert Bol" <> wrote in message
    news:g7crj1$9qc$...
    > Mark B. wrote:
    >
    >> "Huibert Bol" <> wrote in message
    >> news:g7cqut$9qc$...
    >>> Eric Sosman wrote:
    >>>
    >>>> For example, how would you describe the error in
    >>>>
    >>>> #include <stdio.h>
    >>>> int man(void) {
    >>>> return puts ("Hello, world!\n") == EOF;
    >>>> }
    >>>>
    >>>> ? (Yes, this is a trick question.)
    >>>
    >>> It prints an additional newline ;-)

    >>
    >> Doubtful it will print anything...
    >> it's missing the function called at program startup.

    >
    > Dûh, Eric never said it was a complete program!


    Yet his claim that there is an error in the code suggests
    that it should be... unless we have requirements on return
    values from functions named 'man();' that I don't know
    about...
     
    Mark B [Diputsur], Aug 6, 2008
    #6
  7. Huibert Bol

    santosh Guest

    santosh wrote:

    > Eric Sosman wrote:
    >
    > <snip>
    >
    >> There's often some ambiguity in pinpointing "the" error in an
    >> erroneous source. Fundamentally, all that's really known is that
    >> the source is incorrect; diagnosing the nature of its incorrectness
    >> involves imagining a plausible correct source and describing the
    >> "edit distance" between them. Since there are many, many possible
    >> correct sources, there are many possible diagnoses.
    >>
    >> For example, how would you describe the error in
    >>
    >> #include <stdio.h>
    >> int man(void) {
    >> return puts ("Hello, world!\n") == EOF;
    >> }
    >>
    >> ? (Yes, this is a trick question.)

    >
    > Well I suppose there would be no error until the last phase of
    > translation, which will fail because main is not defined, (and you
    > have not told us if the program is freestanding, in which case it
    > would be correct, provided the contents of stdio.h and the definition
    > for puts are supplied by the user.)


    Just to followup, many knowledgeable members of this group have
    previously said that an implementation is not required to reject the
    translation of any program that does not contain a selected #error
    directive. In light of that I would amend my answer above and say that
    no error need be emitted by a compiler for the translation unit given
    above by Eric. A conforming implementation could insert it's own main
    and invoke man from it.
     
    santosh, Aug 6, 2008
    #7
  8. Huibert Bol

    CBFalconer Guest

    Eric Sosman wrote:
    >

    .... snip ...
    >
    > For example, how would you describe the error in
    >
    > #include <stdio.h>
    > int man(void) {
    > return puts ("Hello, world!\n") == EOF;
    > }
    >
    > ? (Yes, this is a trick question.)


    What error? The result is linkable, but can't be a program. It
    always returns 0, barring a write error. Lacking a header file,
    linking will require an extrn statement or equivalent in the
    caller.

    --
    [mail]: Chuck F (cbfalconer at maineline dot net)
    [page]: <http://cbfalconer.home.att.net>
    Try the download section.
     
    CBFalconer, Aug 6, 2008
    #8
  9. Huibert Bol

    CBFalconer Guest

    Eric Sosman wrote:
    > Eric Sosman wrote:
    >> [...]
    >> There's often some ambiguity in pinpointing "the" error in an
    >> erroneous source. Fundamentally, all that's really known is that
    >> the source is incorrect; diagnosing the nature of its incorrectness
    >> involves imagining a plausible correct source and describing the
    >> "edit distance" between them. Since there are many, many possible
    >> correct sources, there are many possible diagnoses.
    >>
    >> For example, how would you describe the error in
    >>
    >> #include <stdio.h>
    >> int man(void) {
    >> return puts ("Hello, world!\n") == EOF;
    >> }
    >>
    >> ? (Yes, this is a trick question.)

    >
    > Huibert Bol, Mark B [Diputsur], and santosh have between them
    > described two errors in this code. To their credit, they did not
    > get sidetracked by the blatant red herring, either! But they all
    > overlooked the *real* error, which is that the code prints "Hello,
    > world!\n\n" instead of "Hello, world!\a\n" ;-)


    Why is that an error? There was no description of a requirement
    for a single \n.

    --
    [mail]: Chuck F (cbfalconer at maineline dot net)
    [page]: <http://cbfalconer.home.att.net>
    Try the download section.
     
    CBFalconer, Aug 6, 2008
    #9
  10. santosh <> writes:
    [...]
    >> Eric Sosman wrote:

    [...]
    >>> For example, how would you describe the error in
    >>>
    >>> #include <stdio.h>
    >>> int man(void) {
    >>> return puts ("Hello, world!\n") == EOF;
    >>> }
    >>>
    >>> ? (Yes, this is a trick question.)

    [...]
    > Just to followup, many knowledgeable members of this group have
    > previously said that an implementation is not required to reject the
    > translation of any program that does not contain a selected #error
    > directive.


    Right.

    > In light of that I would amend my answer above and say that
    > no error need be emitted by a compiler for the translation unit given
    > above by Eric.


    Compilers don't emit errors; they emit diagnostic messages.

    But I think you're conflating two different things: the cases in which
    a compiler must reject a translation unit (only if it contains a
    selected "#error"), and the cases in which it must issue a diagnostic
    message (if there's a violation of a constraint or syntax rule).

    The quoted code contains none of those things, and in fact it's
    perfectly correct -- as far as the compiler can tell. If this were
    real code, it would be *likely* that "man" rather than "main" was a
    typo, but it happens to be a typo that changes a correct translation
    unit to a different correct translation unit. A sufficiently clever
    compiler could warn about it (or about anything), but there's no
    requirement for it to do so.

    > A conforming implementation could insert it's own main
    > and invoke man from it.


    An implementation is specifically forbidden to declare a prototype for
    main (C99 5.1.2.2.1p1); that includes a prototype that's part of a
    definition. Conceivably an implementation could provide a
    non-prototyped definition, but that would be silly.

    On the other hand, some tool in the environment (that's not considered
    part of the C implementation) could always provide a definition for
    main. Typically that tool is a text editor that you use to write your
    own definition of main, but it could be something else.

    --
    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, Aug 6, 2008
    #10
  11. On Wed, 06 Aug 2008 13:28:04 -0700, Keith Thompson wrote:
    > santosh <> writes: [...]
    >> A conforming implementation could insert it's own main
    >> and invoke man from it.

    >
    > An implementation is specifically forbidden to declare a prototype for
    > main (C99 5.1.2.2.1p1); that includes a prototype that's part of a
    > definition. Conceivably an implementation could provide a
    > non-prototyped definition, but that would be silly.


    I suspect 5.1.2.2.1p1 is meant to allow both
    int main(void)
    and
    int main(int, char *[])
    where one or the other would be rejected if the implementation predeclares
    main with a prototype. If santosh meant that an implementation can insert
    its own main function as if it's defined in a separate translation unit,
    then its effect is identical whether the definition includes a prototype
    or not, and since the unprototyped version is not forbidden, the as-if
    rule also allows the prototyped version.
     
    Harald van Dijk, Aug 6, 2008
    #11
  12. Huibert Bol

    santosh Guest

    Keith Thompson wrote:

    > santosh <> writes:
    > [...]
    >>> Eric Sosman wrote:

    > [...]
    >>>> For example, how would you describe the error in
    >>>>
    >>>> #include <stdio.h>
    >>>> int man(void) {
    >>>> return puts ("Hello, world!\n") == EOF;
    >>>> }
    >>>>
    >>>> ? (Yes, this is a trick question.)

    > [...]
    >> Just to followup, many knowledgeable members of this group have
    >> previously said that an implementation is not required to reject the
    >> translation of any program that does not contain a selected #error
    >> directive.

    >
    > Right.
    >
    >> In light of that I would amend my answer above and say that
    >> no error need be emitted by a compiler for the translation unit given
    >> above by Eric.

    >
    > Compilers don't emit errors; they emit diagnostic messages.


    Yes.

    <snip>

    >> A conforming implementation could insert it's own main and invoke man
    >> from it.

    >
    > An implementation is specifically forbidden to declare a prototype for
    > main (C99 5.1.2.2.1p1); that includes a prototype that's part of a
    > definition. Conceivably an implementation could provide a
    > non-prototyped definition, but that would be silly.


    Ah, OK.

    > On the other hand, some tool in the environment (that's not considered
    > part of the C implementation) could always provide a definition for
    > main. Typically that tool is a text editor that you use to write your
    > own definition of main, but it could be something else.


    Right. The post was just a bit of nitpicking, and it appears that I'm
    not up to scratch yet. :)
     
    santosh, Aug 7, 2008
    #12
  13. Huibert Bol

    Guest

    On Aug 6, 9:41 pm, "Mark B [Diputsur]" <> wrote:
    > "Huibert Bol" <> wrote in message
    >
    > news:g7cqut$9qc$...
    >
    > > Eric Sosman wrote:

    >
    > >> For example, how would you describe the error in

    >
    > >> #include <stdio.h>
    > >> int man(void) {
    > >> return puts ("Hello, world!\n") == EOF;
    > >> }

    >
    > >> ? (Yes, this is a trick question.)

    >
    > > It prints an additional newline ;-)

    >
    > Doubtful it will print anything...
    > it's missing the function called at program startup.


    What are you talking about?
     
    , Aug 7, 2008
    #13
    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. Kobu
    Replies:
    7
    Views:
    478
  2. Replies:
    2
    Views:
    1,803
  3. Replies:
    2
    Views:
    927
    Owen Jacobson
    Dec 11, 2007
  4. S_K
    Replies:
    0
    Views:
    680
  5. john
    Replies:
    8
    Views:
    375
    Nick Keighley
    Jun 22, 2010
Loading...

Share This Page