is this declaration correct

Discussion in 'C Programming' started by Raj Pashwar, Jul 18, 2012.

  1. Raj Pashwar

    Raj Pashwar Guest

    Rather than
    include <stdio.h> can I use int printf(const char *,...) correct at all
    places if I only use printf in my program..

    Cheers

    ---
    "You are not going to get it right first time" -> Bjarne Stroustrup
     
    Raj Pashwar, Jul 18, 2012
    #1
    1. Advertising

  2. Raj Pashwar <> writes:
    > Rather than
    > include <stdio.h> can I use int printf(const char *,...) correct at all
    > places if I only use printf in my program..


    You *can*, but there's no good reason to do so.

    It's permitted by 7.1.4p2 (7.1.7 in C89/C90):

    Provided that a library function can be declared without
    reference to any type defined in a header, it is also permissible
    to declare the function and use it without including its
    associated header.

    The <stdio.h> header exists precisely so you don't have write your own
    declarations for standard functions. Using it guarantees (assuming your
    implementation isn't broken) that the declarations will be correct.
    If you write your own declarations, there's always a risk that you'll
    get something wrong.

    And in fact, you have. The declaration you show:

    int printf(const char *,...);

    is correct for C89/C90, but starting with C99 the declaration changed
    to:

    int printf(const char * restrict, ...);

    (Omitting the "restrict" *probably* won't cause any problems, but it
    could inhibit some optimizations.)

    And even that works only because printf doesn't happen to depend on any
    other declarations in <stdio.h>. You can't declare fprintf this way, for
    example, because it depends on the definition of FILE -- and its
    definition can vary substantially from one implementation to another.

    Just write "#include <stdio.h>" and be done with it.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Will write code for food.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Jul 18, 2012
    #2
    1. Advertising

  3. Raj Pashwar

    Eric Sosman Guest

    On 7/18/2012 4:39 PM, Raj Pashwar wrote:
    > Rather than
    > include <stdio.h> can I use int printf(const char *,...) correct at all
    > places if I only use printf in my program..


    You could, but it would be both silly and dangerous. "Silly"
    because the actual declaration in some implementation's <stdio.h>
    might be something like

    int printf(const char restrict *, ...)
    __attribute__((format(printf,1,2)));

    .... where the extra stuff enables implementation-specific extra
    magic, and by using your own free-hand declaration you might lose
    whatever benefits the magic offers. "Dangerous" because strange
    things may happen if you get the declaration wrong -- and note that
    typing ten more characters than `#include <stdio.h>' gives you ten
    additional chances to blunder.

    The Fourth Commandment reads

    If thy header files fail to declare the return types of
    thy library functions, thou shalt declare them thyself
    with the most meticulous care, lest grievous harm befall
    thy program.

    .... and the scholarly annotations thereto say,

    The prophet Ansi, in her wisdom, hath added that thou
    shouldst also scourge thy Suppliers, and demand on pain
    of excommunication that they produce header files that
    declare their library functions. For truly, only they
    know the precise form of the incantation appropriate to
    invoking their magic in the optimal way.

    The prophet hath also commented that it is unwise, and
    leads one into the pits of damnation and subtle bugs, to
    attempt to declare such functions thyself when thy header
    files do the job right.

    But hey, go ahead, do as you please. As the Sowerberrys so
    succinctly put it: "That's - Your - Funeral!"

    --
    Eric Sosman
    d
     
    Eric Sosman, Jul 18, 2012
    #3
  4. Raj Pashwar

    Les Cargill Guest

    Raj Pashwar wrote:
    > Rather than
    > include <stdio.h> can I use int printf(const char *,...) correct at all
    > places if I only use printf in my program..
    >
    > Cheers
    >
    > ---
    > "You are not going to get it right first time" -> Bjarne Stroustrup
    >



    It's better to use the #include. By "better", I mean that
    those who read your code later will see something they're
    more likely to expect.

    --
    Les Cargill
     
    Les Cargill, Jul 18, 2012
    #4
  5. Raj Pashwar

    Raj Pashwar Guest

    On Wed, 18 Jul 2012 14:09:01 -0700, Keith Thompson wrote:

    > Raj Pashwar <> writes:
    >> Rather than
    >> include <stdio.h> can I use int printf(const char *,...) correct at all
    >> places if I only use printf in my program..

    >
    > You *can*, but there's no good reason to do so.
    >
    > It's permitted by 7.1.4p2 (7.1.7 in C89/C90):
    >
    > Provided that a library function can be declared without reference
    > to any type defined in a header, it is also permissible to declare
    > the function and use it without including its associated header.
    >
    > The <stdio.h> header exists precisely so you don't have write your own
    > declarations for standard functions. Using it guarantees (assuming your
    > implementation isn't broken) that the declarations will be correct. If
    > you write your own declarations, there's always a risk that you'll get
    > something wrong.
    >
    > And in fact, you have. The declaration you show:
    >
    > int printf(const char *,...);
    >
    > is correct for C89/C90, but starting with C99 the declaration changed
    > to:
    >
    > int printf(const char * restrict, ...);
    >
    > (Omitting the "restrict" *probably* won't cause any problems, but it
    > could inhibit some optimizations.)
    >
    > And even that works only because printf doesn't happen to depend on any
    > other declarations in <stdio.h>. You can't declare fprintf this way, for
    > example, because it depends on the definition of FILE -- and its
    > definition can vary substantially from one implementation to another.
    >
    > Just write "#include <stdio.h>" and be done with it.


    Thanks for the informations. Conclusion seems to be that my definition
    will work fine though may be sub-optimal.

    I see a few reasons to declare the function without the header, ie speeds
    up compilation, also allows Principal of Data Hiding (localize
    declaration to a block and prevent name leakage elsewhere).

    Cheers,
    Raj
     
    Raj Pashwar, Jul 19, 2012
    #5
  6. Raj Pashwar

    Eric Sosman Guest

    On 7/19/2012 11:19 AM, Raj Pashwar wrote:
    > On Wed, 18 Jul 2012 14:09:01 -0700, Keith Thompson wrote:
    >>[...]
    >> Just write "#include <stdio.h>" and be done with it.

    >
    > Thanks for the informations. Conclusion seems to be that my definition
    > will work fine though may be sub-optimal.
    >
    > I see a few reasons to declare the function without the header, ie speeds
    > up compilation, also allows Principal of Data Hiding (localize
    > declaration to a block and prevent name leakage elsewhere).


    Have you actually measured a compilation speedup? If so,
    how many times must you compile just to recoup the time you've
    spent reading and writing on this thread?

    As for data hiding: For one thing, printf() is not data, but
    a function. For another, an identifier with external linkage will
    "leak" to the entire program no matter what you do!

    --
    Eric Sosman
    d
     
    Eric Sosman, Jul 19, 2012
    #6
  7. Raj Pashwar <> writes:
    > On Wed, 18 Jul 2012 14:09:01 -0700, Keith Thompson wrote:
    >> Raj Pashwar <> writes:
    >>> Rather than
    >>> include <stdio.h> can I use int printf(const char *,...) correct at all
    >>> places if I only use printf in my program..

    >>
    >> You *can*, but there's no good reason to do so.

    [30 lines deleted]
    >> Just write "#include <stdio.h>" and be done with it.

    >
    > Thanks for the informations. Conclusion seems to be that my definition
    > will work fine though may be sub-optimal.


    That may be the conclusion that you drew, but it's certainly not
    what I intended. More precisely, your statement is correct, but
    not particularly useful.

    In particular, if your implementation defines printf with the
    "restrict" keyword, and you declare it without "restrict", it may
    make your program's behavior undefined (I'd have to dig into the
    wording in the standard to be sure). As I said, it's not likely to
    affect your program's behavior in practice, but it could -- which
    means you have one more thing to worry about when you're trying to
    figure out why your program isn't working.

    > I see a few reasons to declare the function without the header, ie speeds
    > up compilation, also allows Principal of Data Hiding (localize
    > declaration to a block and prevent name leakage elsewhere).


    You lose the advantages of possible variations in how the
    implementation declares printf. The speed-up in compilation speed is
    likely to be trivial (have you measured it?), and the time saved is
    almost certainly a tiny fraction of the time we've spent discussing
    it here. 99% of C programmers just write "#include <stdio.h>";
    by doing it differently, you waste the time of anyone reading your
    code, because they'll have to figure out what the heck you're doing.

    As soon as you add a call to fprintf, you *have* to include the header
    because it depends on the definition of FILE. The same applies to any
    function that takes a FILE* argument.

    Keep it simple. Just write "#include <stdio.h>".

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Will write code for food.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Jul 19, 2012
    #7
  8. Raj Pashwar

    Phil Carmody Guest

    Raj Pashwar <> writes:
    > Rather than
    > include <stdio.h> can I use int printf(const char *,...) correct at all
    > places if I only use printf in my program..


    If you have to ask the question, then, for everyone's safety, just use
    the #include.

    Phil
    --
    > I'd argue that there is much evidence for the existence of a God.

    Pics or it didn't happen.
    -- Tom (/. uid 822)
     
    Phil Carmody, Jul 19, 2012
    #8
  9. Raj Pashwar

    Phil Carmody Guest

    Raj Pashwar <> writes:
    > On Wed, 18 Jul 2012 14:09:01 -0700, Keith Thompson wrote:
    > > Raj Pashwar <> writes:

    ....
    > > Just write "#include <stdio.h>" and be done with it.

    >
    > Thanks for the informations. Conclusion seems to be that my definition
    > will work fine though may be sub-optimal.


    That's not what I've seen *anyone* recommend, so how can you conclude
    that? I do know how how - because it was the answer you wanted, and
    you have tacked on "may be sub-optimal" as a way of pretending that
    you've paid attention to the answers you've been given by various
    highly experienced C programmers. (We must have 100 years between us,
    surely?)

    > I see a few reasons to declare the function without the header, ie speeds
    > up compilation,


    I could probably have guessed, given that you asked the question that
    you did, that you would also have some unfounded opinion on speed
    optimisation. I had it too, for about 2 weeks after learning
    C. Fortunately I grew out of it quickly.

    > also allows Principal of Data Hiding (localize
    > declaration to a block and prevent name leakage elsewhere).


    That's not data hiding. That name is not permitted to exist anywhere
    except as the standard library defines it, and everyone is permitted
    to know what the standard library defines.

    You're optimising the wrong thing. Write for future reading, not
    for imaginary keyhole optimisations.

    Phil
    --
    > I'd argue that there is much evidence for the existence of a God.

    Pics or it didn't happen.
    -- Tom (/. uid 822)
     
    Phil Carmody, Jul 19, 2012
    #9
  10. Raj Pashwar

    Phil Carmody Guest

    Ben Bacarisse <> writes:
    > Raj Pashwar <> writes:
    >
    > > On Wed, 18 Jul 2012 14:09:01 -0700, Keith Thompson wrote:
    > >
    > >> Raj Pashwar <> writes:
    > >>> Rather than
    > >>> include <stdio.h> can I use int printf(const char *,...) correct at all
    > >>> places if I only use printf in my program..
    > >>
    > >> You *can*, but there's no good reason to do so.

    > <snip details>
    > >> Just write "#include <stdio.h>" and be done with it.

    > >
    > > Thanks for the informations. Conclusion seems to be that my definition
    > > will work fine though may be sub-optimal.
    > >
    > > I see a few reasons to declare the function without the header, ie speeds
    > > up compilation, also allows Principal of Data Hiding (localize
    > > declaration to a block and prevent name leakage elsewhere).

    >
    > The second point is rather odd because it conflicts with another: the
    > principle of least surprise. C programmer expect printf to be, well,
    > the global printf they know, so localising its declaration will surprise
    > your readers.


    Dang. That's the kind of thing that was going through my head, but
    my expression of the idea was pants. You've nailed it though.

    Raj - listen to Ben, he speaks wise words.

    Phil
    --
    > I'd argue that there is much evidence for the existence of a God.

    Pics or it didn't happen.
    -- Tom (/. uid 822)
     
    Phil Carmody, Jul 19, 2012
    #10
  11. Raj Pashwar <> writes:

    > On Wed, 18 Jul 2012 14:09:01 -0700, Keith Thompson wrote:
    >
    >> Raj Pashwar <> writes:
    >>> Rather than
    >>> include <stdio.h> can I use int printf(const char *,...) correct at all
    >>> places if I only use printf in my program..

    >>
    >> You *can*, but there's no good reason to do so.

    <snip details>
    >> Just write "#include <stdio.h>" and be done with it.

    >
    > Thanks for the informations. Conclusion seems to be that my definition
    > will work fine though may be sub-optimal.
    >
    > I see a few reasons to declare the function without the header, ie speeds
    > up compilation, also allows Principal of Data Hiding (localize
    > declaration to a block and prevent name leakage elsewhere).


    The second point is rather odd because it conflicts with another: the
    principle of least surprise. C programmer expect printf to be, well,
    the global printf they know, so localising its declaration will surprise
    your readers.

    Note that you posted here to ask. A good proportion of people reading
    your code will not know the answer either. Do you want them to be
    puzzled (or to have to take your /* honest, it's legal! */ comment at
    face value)?

    --
    Ben.
     
    Ben Bacarisse, Jul 19, 2012
    #11
  12. Raj Pashwar

    Ben Pfaff Guest

    Raj Pashwar <> writes:

    > I see a few reasons to declare the function without the header, ie speeds
    > up compilation, also allows Principal of Data Hiding (localize
    > declaration to a block and prevent name leakage elsewhere).


    You've got it backwards. The declaration of printf() is already
    nicely hidden from you in <stdio.h>. You're trying to make it
    visible.
     
    Ben Pfaff, Jul 19, 2012
    #12
  13. Raj Pashwar

    Tim Rentsch Guest

    Raj Pashwar <> writes:

    > Rather than
    > include <stdio.h> can I use int printf(const char *,...) correct at all
    > places if I only use printf in my program..


    1. Yes.

    2. There's a simple check you can do -- make a test file containing just

    #include <stdio.h>
    int printf(const char *,...);

    and compile it (using a conforming mode, eg, 'gcc -ansi -pedantic',
    and/or 'gcc -std=c99 -pedantic' (better, '-pedantic-errors' in both
    cases). Observe that no warning or errors are produced.

    3. If you are interested in other questions like this, it's worth
    your while to get a copy of the C Standard document (or a very
    close approximation to) and try to discover an answer yourself
    by reading the relevant sections. Here are links for C99 and
    C11, respectively:

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

    Download them NOW!

    4. Ignore the scare tactics of the naysayers implying that this
    declaration of printf is somehow less reliable than just
    including <stdio.h>. The declaration you give is absolutely
    guaranteed to work. The idea that it will have some effect
    on performance is conceivable but not likely, and even less
    likely to be relevant.

    5. Personally, I would tend to favor #include <stdio.h> over just
    a bare declaration of printf() in almost all circumstances,
    but that's a personal judgment, not a logical one. If you
    think it's important to limit the scope of where printf() is
    callable, using local declarations does (in C99 and C11)
    provide a way of doing that. Although, if that's true,
    probably it is worth separating out those functions that use
    printf() and put them in a separate .c file, and include
    <stdio.h> for that file. Try different possibilities, see
    what provides the best overall balance.
     
    Tim Rentsch, Jul 21, 2012
    #13
  14. Raj Pashwar

    Tim Rentsch Guest

    Keith Thompson <> writes:

    > Raj Pashwar <> writes:
    >> On Wed, 18 Jul 2012 14:09:01 -0700, Keith Thompson wrote:
    >>> Raj Pashwar <> writes:
    >>>> Rather than
    >>>> include <stdio.h> can I use int printf(const char *,...) correct at all
    >>>> places if I only use printf in my program..
    >>>
    >>> You *can*, but there's no good reason to do so.

    > [30 lines deleted]
    >>> Just write "#include <stdio.h>" and be done with it.

    >>
    >> Thanks for the informations. Conclusion seems to be that my definition
    >> will work fine though may be sub-optimal.

    >
    > That may be the conclusion that you drew, but it's certainly not
    > what I intended. More precisely, your statement is correct, but
    > not particularly useful.
    >
    > In particular, if your implementation defines printf with the
    > "restrict" keyword, and you declare it without "restrict", it may
    > make your program's behavior undefined (I'd have to dig into the
    > wording in the standard to be sure). [snip]


    Now that it is being pointed out, I'm confident you will
    find the relevant passage or passages and post a correction.
     
    Tim Rentsch, Jul 21, 2012
    #14
  15. Raj Pashwar

    Tim Rentsch Guest

    Eric Sosman <> writes:

    > On 7/19/2012 11:19 AM, Raj Pashwar wrote:
    >> On Wed, 18 Jul 2012 14:09:01 -0700, Keith Thompson wrote:
    >>>[...]
    >>> Just write "#include <stdio.h>" and be done with it.

    >>
    >> [snip]
    >> I see a few reasons to declare the function without the header, ie speeds
    >> up compilation, also allows Principal of Data Hiding (localize
    >> declaration to a block and prevent name leakage elsewhere).

    >
    > [snip] an identifier with external linkage will
    > "leak" to the entire program no matter what you do!


    Not in the sense that he means it, ie, the declaration
    will be visible only in the scope (or scopes) where
    it is declared. It won't be visible in other (non-nested)
    scopes. In C99, that would mean other uses of printf()
    would cause compilation errors.
     
    Tim Rentsch, Jul 21, 2012
    #15
  16. Raj Pashwar

    Phil Carmody Guest

    Tim Rentsch <> writes:
    > Raj Pashwar <> writes:
    >
    > > Rather than
    > > include <stdio.h> can I use int printf(const char *,...) correct at all
    > > places if I only use printf in my program..

    ....
    > 4. Ignore the scare tactics of the naysayers implying that this
    > declaration of printf is somehow less reliable than just
    > including <stdio.h>. The declaration you give is absolutely
    > guaranteed to work. The idea that it will have some effect
    > on performance is conceivable but not likely, and even less
    > likely to be relevant.


    4b. Ignore the scare tactics of those who tell you, once you've
    included stdlib.h, to write:

    type_t *p = malloc(sizeof(*p));

    rather than:

    type_t *p = (type_t *)malloc(sizeof(type_t));

    The former is absolutely guaranteed to work.


    Good advice, no? I'm tempted to say a cost-risk-benefit analysis
    would favour my advice even more than yours, given what I've
    actually seen go wrong over the decades. E.g. gcc's format mismatch
    warnings trap many portability gotchas as well as grosser bugs -
    cost zero, risk zero, benefit palpable.

    Phil
    --
    > I'd argue that there is much evidence for the existence of a God.

    Pics or it didn't happen.
    -- Tom (/. uid 822)
     
    Phil Carmody, Jul 21, 2012
    #16
  17. Raj Pashwar

    Tim Rentsch Guest

    Phil Carmody <> writes:

    > Raj Pashwar <> writes:

    [snip]
    >> also allows Principal of Data Hiding (localize
    >> declaration to a block and prevent name leakage elsewhere).

    >
    > That's not data hiding. That name is not permitted to exist anywhere
    > except as the standard library defines it, [snip[


    That's not exactly right. Defining a library function (such
    as printf()) yourself is undefined behavior, but the Standard
    doesn't actually disallow it. There are lots of implementations
    where defining a library function yourself will work fine,
    and "override" the standard function, by means of weak symbol
    table entries in standard library object modules.

    I admit this distinction goes beyond what the OP was asking
    about, but I think it's important to give correct statements
    and not gloss over these kinds of distinctions, even though
    they might seem minor relative to the question being asked.
     
    Tim Rentsch, Jul 21, 2012
    #17
  18. Raj Pashwar

    Tim Rentsch Guest

    Ben Bacarisse <> writes:

    > Raj Pashwar <> writes:
    >
    >> On Wed, 18 Jul 2012 14:09:01 -0700, Keith Thompson wrote:
    >>
    >>> Raj Pashwar <> writes:
    >>>> Rather than
    >>>> include <stdio.h> can I use int printf(const char *,...) correct at all
    >>>> places if I only use printf in my program..
    >>>
    >>> You *can*, but there's no good reason to do so.

    > <snip details>
    >>> Just write "#include <stdio.h>" and be done with it.

    >>
    >> Thanks for the informations. Conclusion seems to be that my definition
    >> will work fine though may be sub-optimal.
    >>
    >> I see a few reasons to declare the function without the header, ie speeds
    >> up compilation, also allows Principal of Data Hiding (localize
    >> declaration to a block and prevent name leakage elsewhere).

    >
    > The second point is rather odd because it conflicts with another: the
    > principle of least surprise.


    Not that this matters really, but historically the Law of Least
    Astonishment (as it used to be called) arose in connection with
    the design of programming languages rather than the design of
    programs (assuming my memory on the subject is correct, which it
    may not be). So the allusion to it here caused (for me at least)
    the more general principle to be violated.

    > C programmer expect printf to be, well, the global printf they
    > know, so localising its declaration will surprise your readers.


    Will it? If I saw a local declaration of printf(), I think I
    would assume the writer wanted to limit the scope of where the
    identifier will be used, just like any other declaration. Is
    there reason to believe his readers are confused on this point?
    I don't see any reason a priori to expect they will be.

    > Note that you posted here to ask. A good proportion of people
    > reading your code will not know the answer either. Do you want
    > them to be puzzled (or to have to take your /* honest, it's
    > legal! */ comment at face value)?


    Oh, but his question is a little bit different, namely, is this
    the right way to write the declaration? The readers don't need
    to worry (and probably won't worry) about that question, since
    he is giving them (presumably) a working program. It's possible
    of course that some of them will wonder about whether it's legal,
    and take the trouble to find out, but that doesn't strike me as
    a bad thing; it's only when unwary readers are confused that I
    think some sort of advisory is called for, but to me that doesn't
    seem to be the case here.
     
    Tim Rentsch, Jul 21, 2012
    #18
  19. Raj Pashwar

    Tim Rentsch Guest

    Ben Pfaff <> writes:

    > Raj Pashwar <> writes:
    >
    >> I see a few reasons to declare the function without the header, ie speeds
    >> up compilation, also allows Principal of Data Hiding (localize
    >> declaration to a block and prevent name leakage elsewhere).

    >
    > You've got it backwards. The declaration of printf() is already
    > nicely hidden from you in <stdio.h>. You're trying to make it
    > visible.


    Actually what he wants is to _limit_ the visibility to something
    smaller than file scope. To do that, it is necessary to declare
    printf() directly, since doing a #include has defined behavior only
    outside of all external defintions (and in particular, outside of
    any function body).
     
    Tim Rentsch, Jul 21, 2012
    #19
  20. Tim Rentsch <> writes:
    > Keith Thompson <> writes:
    >> Raj Pashwar <> writes:
    >>> On Wed, 18 Jul 2012 14:09:01 -0700, Keith Thompson wrote:
    >>>> Raj Pashwar <> writes:
    >>>>> Rather than
    >>>>> include <stdio.h> can I use int printf(const char *,...) correct at all
    >>>>> places if I only use printf in my program..
    >>>>
    >>>> You *can*, but there's no good reason to do so.

    >> [30 lines deleted]
    >>>> Just write "#include <stdio.h>" and be done with it.
    >>>
    >>> Thanks for the informations. Conclusion seems to be that my definition
    >>> will work fine though may be sub-optimal.

    >>
    >> That may be the conclusion that you drew, but it's certainly not
    >> what I intended. More precisely, your statement is correct, but
    >> not particularly useful.
    >>
    >> In particular, if your implementation defines printf with the
    >> "restrict" keyword, and you declare it without "restrict", it may
    >> make your program's behavior undefined (I'd have to dig into the
    >> wording in the standard to be sure). [snip]

    >
    > Now that it is being pointed out, I'm confident you will
    > find the relevant passage or passages and post a correction.


    Not exactly.

    The OP's declaration of printf is:

    int printf(const char *,...);

    That's compatible with the C89/C90 standard declaration of printf:

    int printf(const char *format, ...);

    but the C99 (and later) declaration is:

    int printf(const char *restrict format, ...);

    I'll refer to N1570.

    6.5.2.2p6 (Function calls):

    If the function is defined with a type that includes a prototype,
    and either the prototype ends with an ellipsis (, ...) or the
    types of the arguments after promotion are not compatible with
    the types of the parameters, the behavior is undefined.

    6.7.3p10 (Type qualifiers):

    For two qualified types to be compatible, both shall have the
    identically qualified version of a compatible type; the order
    of type qualifiers within a list of specifiers or qualifiers
    does not affect the specified type.

    ("restrict" is a type qualifier.)

    6.7.6p2 (Declarators):

    Each declarator declares one identifier, and asserts that
    when an operand of the same form as the declarator appears
    in an expression, it designates a function or object with the
    scope, storage duration, and type indicated by the declaration
    specifiers.

    So the types "const char*" and "const char *restrict" are not
    compatible, and therefore the function types are incompatible.
    In fact, 6.7.6p2 requires them to be the same type, not merely
    compatible. (So I didn't really need 6.5.2.2p6 or 6.7.3p10, but
    I had already copy-and-pasted them, so I'll leave them here.)

    My interpretation of all this is that a call to printf in the scope
    of a declaration

    int printf(const char*, ...);

    has well defined behavior in C89/C90, but undefined behavior in
    C99 and C11.

    (For most implementations, I would expect the consequence to be that
    the call works just as it would if printf were declared correctly.)

    I also conclude that this (which you suggested elsewhere in this
    thread):

    #include <stdio.h>
    int printf(const char *, ...);

    or this:

    int printf(const char *restrict, ...);
    int printf(const char *, ...);

    violates the constraint in 6.7p4:

    All declarations in the same scope that refer to the same object
    or function shall specify compatible types.

    gcc fails to diagnose this, though it does complain if one of the
    declarations is missing the "const".

    There is a counterargument to all this. 6.2.5p26 says:

    The qualified or unqualified versions of a type are distinct
    types that belong to the same type category and have the same
    representation and alignment requirements.

    with a footnote:

    The same representation and alignment requirements are meant
    to imply interchangeability as arguments to functions, return
    values from functions, and members of unions.

    Is that what you had in mind?

    So by declaring printf yourself (without the "restrict" rather
    than including <stdio.h>, you are at worst invoking undefined
    behavior, and at best depending on a potentially ambiguous line
    of reasoning -- and imposing that line of reasoning on anyone who
    reads or maintains the code. It *might* save some time by avoiding
    having to process <stdio.h> (surely a tiny fraction of the time
    we've spent debating it). And it doesn't extend to functions that
    depend on the declaration of FILE.

    Or you can just write "#include <stdio.h>", which is *much*
    easier, guaranteed to be correct, and consistent with what 99%
    of C programmers use and expect.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Will write code for food.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Jul 22, 2012
    #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. joon
    Replies:
    1
    Views:
    519
    Roedy Green
    Jul 8, 2003
  2. Dan

    correct or not correct?

    Dan, Oct 2, 2003, in forum: HTML
    Replies:
    7
    Views:
    446
  3. Chris Bore
    Replies:
    2
    Views:
    305
    Pierre Asselin
    Dec 8, 2006
  4. J.Ram
    Replies:
    7
    Views:
    655
  5. froil
    Replies:
    12
    Views:
    315
    Gunnar Hjalmarsson
    Mar 2, 2006
Loading...

Share This Page