is this declaration correct

Discussion in 'C Programming' started by barry, Jun 17, 2010.

  1. barry

    barry 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..
    "You are not going to get it right first time" -> Bjarne Stroustrup
    barry, Jun 17, 2010
    #1
    1. Advertising

  2. barry <> 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..


    Yes and no.

    Yes, in C90 that's the correct declaration.

    In C99, the declaration of printf is
    int printf(const char * restrict format, ...);
    I'm not sure what the standard says about defining a function with
    "restrict" and declaring it without "restrict".

    But why would you want to do this? I can't think of any good reason not
    to just use

    #include <stdio.h>

    --
    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, Jun 18, 2010
    #2
    1. Advertising

  3. Keith Thompson <> wrote:
    > barry <> writes:
    > > include <stdio.h> can I use int printf(const char *,...)

    ....
    > In C99, the declaration of printf is
    >     int printf(const char * restrict format, ...);
    > I'm not sure what the standard says about defining a function with
    > "restrict" and declaring it without "restrict".


    N1256: 6.7.5.3p15: "... (In the determination of type
    compatibility ... each parameter declared with qualified type
    is taken as having the unqualified version of its declared
    type.)"

    So, yes, it's fine in C99.

    > But why would you want to do this?
    >
    > I can't think of any good reason not to just use
    >
    >     #include <stdio.h>


    Perhaps:

    1) to shorten compile time.
    2) declaring printf at block scope localises the
    declaration.
    3) a freestanding implementation may not supply a stdio.h,
    it may be possible to link one in.

    --
    Peter
    Peter Nilsson, Jun 18, 2010
    #3
  4. barry

    sandeep Guest

    Keith Thompson writes:
    > barry <> 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..

    >
    > Yes and no.
    >
    > Yes, in C90 that's the correct declaration.
    >
    > In C99, the declaration of printf is
    > int printf(const char * restrict format, ...);
    > I'm not sure what the standard says about defining a function with
    > "restrict" and declaring it without "restrict".


    Also printf may be a macro not a function, for example if I was
    implementing a compiler then I would implement fprintf then have
    #define printf(s,...) (fprintf(stdout,(s),__VA_ARGS__))
    in <stdio.h>.

    In this situation linking will fail if you provide your own declaration
    of printf!!
    sandeep, Jun 18, 2010
    #4
  5. sandeep wrote:

    > Keith Thompson writes:
    >> In C99, the declaration of printf is
    >> int printf(const char * restrict format, ...);
    >> I'm not sure what the standard says about defining a function with
    >> "restrict" and declaring it without "restrict".

    >
    > Also printf may be a macro not a function, for example if I was
    > implementing a compiler then I would implement fprintf then have
    > #define printf(s,...) (fprintf(stdout,(s),__VA_ARGS__))
    > in <stdio.h>.
    >
    > In this situation linking will fail if you provide your own declaration
    > of printf!!


    In that case your implementation would not be a conforming one.
    It even must allow a
    #undef printf
    and still accept calls to printf().

    -- Ralf
    Ralf Damaschke, Jun 18, 2010
    #5
  6. barry

    Eric Sosman Guest

    On 6/17/2010 10:51 PM, Peter Nilsson wrote:
    > Keith Thompson<> wrote:
    >> barry<> writes:
    >>> include<stdio.h> can I use int printf(const char *,...)

    > ...
    >> In C99, the declaration of printf is
    >> int printf(const char * restrict format, ...);
    >> I'm not sure what the standard says about defining a function with
    >> "restrict" and declaring it without "restrict".

    >
    > N1256: 6.7.5.3p15: "... (In the determination of type
    > compatibility ... each parameter declared with qualified type
    > is taken as having the unqualified version of its declared
    > type.)"
    >
    > So, yes, it's fine in C99.
    >
    >> But why would you want to do this?
    >>
    >> I can't think of any good reason not to just use
    >>
    >> #include<stdio.h>

    >
    > Perhaps:
    >
    > 1) to shorten compile time.


    IMHO it would take a very large number of compilations to
    recoup the time already spent posting the question and reading
    answers.

    > 2) declaring printf at block scope localises the
    > declaration.


    Yes, but why? This would only be advantageous if you also
    wanted to use `printf' as an identifier for something else entirely,
    like `static double printf[42][36];' or something -- and that's just
    plain stupid.

    > 3) a freestanding implementation may not supply a stdio.h,
    > it may be possible to link one in.


    True -- But in that case, we don't know whether the offered
    declaration is correct or not, since we don't know what the
    free-standing system's `printf' does.

    --
    Eric Sosman
    lid
    Eric Sosman, Jun 18, 2010
    #6
  7. Peter Nilsson <> writes:
    > Keith Thompson <> wrote:

    [...]
    >> I can't think of any good reason not to just use
    >>
    >>     #include <stdio.h>

    >
    > Perhaps:
    >
    > 1) to shorten compile time.


    If you're compiling a very large number of files on a slow system, the
    speedup might even be noticeable -- but I doubt that it would exceed the
    extra time spent maintaining the code.

    > 2) declaring printf at block scope localises the
    > declaration.


    How is that useful?

    > 3) a freestanding implementation may not supply a stdio.h,
    > it may be possible to link one in.


    Ok, that's possible (though an implementation that provides printf
    but doesn't declare it in a header is not exactly friendly).

    --
    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, Jun 18, 2010
    #7
  8. barry

    Guest

    On Jun 18, 11:25 am, sandeep <> wrote:
    > Also printf may be a macro not a function, for example if I was
    > implementing a compiler then I would implement fprintf then have
    > #define printf(s,...) (fprintf(stdout,(s),__VA_ARGS__))
    > in <stdio.h>.


    That's not a valid macro implementation of printf. Consider
    printf("Hello world\n");
    , Jun 18, 2010
    #8
  9. barry

    sandeep Guest

    Ralf Damaschke writes:
    > sandeep wrote:
    >
    >> Keith Thompson writes:
    >>> In C99, the declaration of printf is
    >>> int printf(const char * restrict format, ...);
    >>> I'm not sure what the standard says about defining a function with
    >>> "restrict" and declaring it without "restrict".

    >>
    >> Also printf may be a macro not a function, for example if I was
    >> implementing a compiler then I would implement fprintf then have
    >> #define printf(s,...) (fprintf(stdout,(s),__VA_ARGS__)) in <stdio.h>.
    >>
    >> In this situation linking will fail if you provide your own declaration
    >> of printf!!

    >
    > In that case your implementation would not be a conforming one. It even
    > must allow a
    > #undef printf
    > and still accept calls to printf().
    >
    > -- Ralf


    I think standard library functions can be implemented as macros, for
    example in gcc putc is a macro.
    sandeep, Jun 18, 2010
    #9
  10. barry

    Eric Sosman Guest

    On 6/18/2010 5:23 PM, sandeep wrote:
    >
    > I think standard library functions can be implemented as macros, for
    > example in gcc putc is a macro.


    Yes, but no Standard library function can be implemented
    *only* as a macro.

    Are you the same Sandeep who's writing his Master's thesis on
    the C Standard library? I guess not, because someone undertaking
    such an effort would surely have read the Standard's description
    of that library, and would have come across 7.1.4p1. Read it, and
    you'll then know something the other Sandeep has already learned.

    --
    Eric Sosman
    lid
    Eric Sosman, Jun 18, 2010
    #10
  11. barry

    sandeep Guest

    Eric Sosman writes:
    > On 6/18/2010 5:23 PM, sandeep wrote:
    >>
    >> I think standard library functions can be implemented as macros, for
    >> example in gcc putc is a macro.

    >
    > Yes, but no Standard library function can be implemented
    > *only* as a macro.


    In this case gcc is nonconforming...

    $ nm /usr/lib/libc.a 2>&1 | grep putc
    putchar.o:
    0000000000000000 T putchar
    putchar_u.o:
    0000000000000000 T putchar_unlocked
    fputc.o:
    0000000000000000 T fputc
    putc.o:
    0000000000000000 T _IO_putc
    0000000000000000 W putc
    fputc_u.o:
    0000000000000000 T fputc_unlocked
    putc_u.o:
    0000000000000000 T putc_unlocked
    00000000000000f0 T __argp_fmtstream_putc

    You see that putc is ONLY provided as a macro!

    > Are you the same Sandeep who's writing his Master's thesis on
    > the C Standard library? I guess not, because someone undertaking such
    > an effort would surely have read the Standard's description of that
    > library, and would have come across 7.1.4p1. Read it, and you'll then
    > know something the other Sandeep has already learned.


    Of course I can't memorize every detail, however I will browse the
    Standard and get the main points and look at any sections on topics of my
    specialization.
    sandeep, Jun 19, 2010
    #11
  12. sandeep <> writes:

    > Eric Sosman writes:
    >> On 6/18/2010 5:23 PM, sandeep wrote:
    >>>
    >>> I think standard library functions can be implemented as macros, for
    >>> example in gcc putc is a macro.

    >>
    >> Yes, but no Standard library function can be implemented
    >> *only* as a macro.

    >
    > In this case gcc is nonconforming...
    >
    > $ nm /usr/lib/libc.a 2>&1 | grep putc
    > putchar.o:
    > 0000000000000000 T putchar
    > putchar_u.o:
    > 0000000000000000 T putchar_unlocked
    > fputc.o:
    > 0000000000000000 T fputc
    > putc.o:
    > 0000000000000000 T _IO_putc
    > 0000000000000000 W putc
    > fputc_u.o:
    > 0000000000000000 T fputc_unlocked
    > putc_u.o:
    > 0000000000000000 T putc_unlocked
    > 00000000000000f0 T __argp_fmtstream_putc
    >
    > You see that putc is ONLY provided as a macro!


    How you conclude that? Did you try this, for example:

    #include <stdio.h>

    int main(void)
    {
    (putc)('x', stdout);
    (putc)('\n', stdout);
    return 0;
    }

    <snip>
    --
    Ben.
    Ben Bacarisse, Jun 19, 2010
    #12
  13. barry

    Ian Collins Guest

    On 06/19/10 10:28 PM, Ben Bacarisse wrote:
    > sandeep<> writes:
    >
    >> Eric Sosman writes:
    >>> On 6/18/2010 5:23 PM, sandeep wrote:
    >>>>
    >>>> I think standard library functions can be implemented as macros, for
    >>>> example in gcc putc is a macro.
    >>>
    >>> Yes, but no Standard library function can be implemented
    >>> *only* as a macro.

    >>
    >> In this case gcc is nonconforming...
    >>
    >> $ nm /usr/lib/libc.a 2>&1 | grep putc
    >> putchar.o:
    >> 0000000000000000 T putchar
    >> putchar_u.o:
    >> 0000000000000000 T putchar_unlocked
    >> fputc.o:
    >> 0000000000000000 T fputc
    >> putc.o:
    >> 0000000000000000 T _IO_putc
    >> 0000000000000000 W putc
    >> fputc_u.o:
    >> 0000000000000000 T fputc_unlocked
    >> putc_u.o:
    >> 0000000000000000 T putc_unlocked
    >> 00000000000000f0 T __argp_fmtstream_putc
    >>
    >> You see that putc is ONLY provided as a macro!

    >
    > How you conclude that? Did you try this, for example:
    >
    > #include<stdio.h>
    >
    > int main(void)
    > {
    > (putc)('x', stdout);
    > (putc)('\n', stdout);
    > return 0;
    > }


    Or

    #include <stdio.h>

    typedef int (*fn)(int, FILE*);

    int main(void)
    {
    fn f = &putc;
    }

    --
    Ian Collins
    Ian Collins, Jun 19, 2010
    #13
  14. barry

    Eric Sosman Guest

    On 6/19/2010 7:00 AM, Ian Collins wrote:
    > On 06/19/10 10:28 PM, Ben Bacarisse wrote:
    >> sandeep<> writes:
    >>
    >>> Eric Sosman writes:
    >>>> On 6/18/2010 5:23 PM, sandeep wrote:
    >>>>>
    >>>>> I think standard library functions can be implemented as macros, for
    >>>>> example in gcc putc is a macro.
    >>>>
    >>>> Yes, but no Standard library function can be implemented
    >>>> *only* as a macro.
    >>>
    >>> In this case gcc is nonconforming...
    >>>
    >>> $ nm /usr/lib/libc.a 2>&1 | grep putc
    >>> putchar.o:
    >>> 0000000000000000 T putchar
    >>> putchar_u.o:
    >>> 0000000000000000 T putchar_unlocked
    >>> fputc.o:
    >>> 0000000000000000 T fputc
    >>> putc.o:
    >>> 0000000000000000 T _IO_putc
    >>> 0000000000000000 W putc
    >>> fputc_u.o:
    >>> 0000000000000000 T fputc_unlocked
    >>> putc_u.o:
    >>> 0000000000000000 T putc_unlocked
    >>> 00000000000000f0 T __argp_fmtstream_putc
    >>>
    >>> You see that putc is ONLY provided as a macro!

    >>
    >> How you conclude that? Did you try this, for example:
    >>
    >> #include<stdio.h>
    >>
    >> int main(void)
    >> {
    >> (putc)('x', stdout);
    >> (putc)('\n', stdout);
    >> return 0;
    >> }

    >
    > Or
    >
    > #include <stdio.h>
    >
    > typedef int (*fn)(int, FILE*);
    >
    > int main(void)
    > {
    > fn f = &putc;
    > }


    Or

    #include <stdio.h>
    #undef putc
    int main(void) {
    putc('!', stdout);
    putc('\n', stdout);
    return 0;
    }

    --
    Eric Sosman
    lid
    Eric Sosman, Jun 19, 2010
    #14
  15. On Sat, 19 Jun 2010 10:22:06 +0000 (UTC), sandeep <>
    wrote:

    > Eric Sosman writes:
    > > On 6/18/2010 5:23 PM, sandeep wrote:
    > >>
    > >> I think standard library functions can be implemented as macros, for
    > >> example in gcc putc is a macro.

    > >
    > > Yes, but no Standard library function can be implemented
    > > *only* as a macro.

    >

    Note that this wording is a bit subtle. The things specified in clause
    7 as functions *may* *also* be implemented as macros. A few things
    *specified* as macros with arguments, aka function-like macros, do not
    need to be functions: assert setjmp fpclassify/isless/etc va_start*
    va_arg* offsetof* INT[bits|MAX]_C* (the * ones obviously can't be
    functions because they take nonvalues and/or return varying types.)

    > In this case gcc is nonconforming...
    >

    (Technically this isn't gcc; it's the library used with gcc, perhaps
    glibc, which together make up a C implementation.)

    > $ nm /usr/lib/libc.a 2>&1 | grep putc
    > putchar.o:
    > 0000000000000000 T putchar
    > putchar_u.o:
    > 0000000000000000 T putchar_unlocked
    > fputc.o:
    > 0000000000000000 T fputc
    > putc.o:
    > 0000000000000000 T _IO_putc
    > 0000000000000000 W putc
    > fputc_u.o:
    > 0000000000000000 T fputc_unlocked
    > putc_u.o:
    > 0000000000000000 T putc_unlocked
    > 00000000000000f0 T __argp_fmtstream_putc
    >
    > You see that putc is ONLY provided as a macro!
    >

    Look again. The 'W' in putc.o *is* a global definition. Merely a
    'weak' one that can be overridden by another (user) definition.

    That's okay; a conforming implementation (of the library) must have
    actual library routines that standard C code *can* reference; if
    nonstandard C code defines its own e.g. putc that is UB: the
    implementation *may* (detect and) report the error; it *may* just
    malfunction; it *may* (and this one does) let the user win; it *may*
    create nasal demons, though that's rather hard to implement.
    David Thompson, Jul 2, 2010
    #15
    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:
    515
    Roedy Green
    Jul 8, 2003
  2. Dan

    correct or not correct?

    Dan, Oct 2, 2003, in forum: HTML
    Replies:
    7
    Views:
    441
  3. Chris Bore
    Replies:
    2
    Views:
    297
    Pierre Asselin
    Dec 8, 2006
  4. J.Ram
    Replies:
    7
    Views:
    650
  5. froil
    Replies:
    12
    Views:
    310
    Gunnar Hjalmarsson
    Mar 2, 2006
Loading...

Share This Page