variadic functions

Discussion in 'C Programming' started by Frank, Oct 3, 2009.

  1. Frank

    Frank Guest

    I seem to be interested in places where C and fortran are different.
    An example is:
    #include <stdio.h>
    #include <string.h>
    int main() {
    char s[10];
    strcpy(s,"abcdefg");
    strchr(s,'c')[1]='x';
    printf("%s\n",s);
    printf ("execution was here");
    return 0;
    }

    Can someone say with clarity exactly what happens in the this line:
    strchr(s,'c')[1]='x';
    I think it's called array subscripting. Can someone post an example
    of useful code that uses this feature?

    Another thing we don't have are variadic functions. This was
    particularly hard to understand from the K&R material, where I came
    away from it thinking the ellipses were added by the book as opposed
    to a language token.

    #include <string.h>
    int main(void)
    {
    int printf(const char *, ...);
    char s[10];
    strcpy(s,"abcdefg");
    strchr(s,'c')[1]='x';
    printf("%s\n",s);
    printf ("execution was here");
    return 0;
    }
    How is this program different from the first?
    Frank, Oct 3, 2009
    #1
    1. Advertising

  2. Frank

    Eric Sosman Guest

    Frank wrote:
    > I seem to be interested in places where C and fortran are different.


    I seem to hope the seeming resembles reality.

    > An example is:
    > #include <stdio.h>
    > #include <string.h>
    > int main() {
    > char s[10];
    > strcpy(s,"abcdefg");
    > strchr(s,'c')[1]='x';
    > printf("%s\n",s);
    > printf ("execution was here");
    > return 0;
    > }
    >
    > Can someone say with clarity exactly what happens in the this line:
    > strchr(s,'c')[1]='x';
    > I think it's called array subscripting. Can someone post an example
    > of useful code that uses this feature?


    There are two things about C you need to know to make sense
    of this.

    The first is sometimes called The Rule: In most contexts
    (all but two), writing the name of an array in an expression is
    the same as writing a pointer to the array's first element.
    That's why the strcpy() and strchr() and printf() calls' use of
    the array name s is the same as writing &s[0], a pointer to the
    zero'th element of the array s.

    The second is that the indexing operator [] is *defined*
    in terms of arithmetic on pointers: arr[j] means *(arr+j). This
    causes giggles among immature schoolchildren when they suddenly
    realize that addition is commutative, so *(arr+j) is the same as
    *(j+arr), which is the same as j[arr]. Tee hee, snicker.

    Since indexing is defined in terms of pointer arithmetic,
    you don't need to do it on an actual array: You can do it with
    any pointer and any integer (as long as the result is in range).
    So arr[j] is legal, but so is p[j] when p is a pointer (or when
    p is an integer and j is a pointer, tee hee, snicker). Apply
    The Rule: p[j] means *(p+j). This use of the same notation with
    both arrays and pointers is sometimes referred to as "equivalence
    of pointers and arrays," which is slightly misleading because
    they are not entirely equivalent. (Examine the values of
    sizeof(s) and sizeof(&s[0]) to see one inequivalence.)

    Okay, now you've got what you need to understand the line
    that puzzles you. strchr() returns a pointer to char, a char*.
    By The Rule, strchr(s,'c')[1] means *(strchr(s,'c')+1). As long
    as strchr() doesn't return NULL (which it doesn't in your case),
    the addition inside the parentheses is valid (it is *not* valid
    to add or subtract from a NULL-valued pointer). So: strchr(s,'c')
    returns a pointer to the 'c' at the [2] position in s, adding 1
    produces a pointer to one place further along -- to the [3] spot
    in s, where the 'd' resides, and then you store 'x' in that spot.

    > Another thing we don't have are variadic functions. This was
    > particularly hard to understand from the K&R material, where I came
    > away from it thinking the ellipses were added by the book as opposed
    > to a language token.
    >
    > #include <string.h>
    > int main(void)
    > {
    > int printf(const char *, ...);
    > char s[10];
    > strcpy(s,"abcdefg");
    > strchr(s,'c')[1]='x';
    > printf("%s\n",s);
    > printf ("execution was here");
    > return 0;
    > }
    > How is this program different from the first?


    It's sillier. The free-hand declaration of printf() is
    correct and legal (in C99 it is not quite perfect, but still
    legal as far as I know), but dumb. Many functions from the
    Standard library *can* be declared free-hand, but it's silly
    to do so. Some can be so declared and the program will work,
    but you may find that it runs slower than if you'd included
    the proper header. And there are several library functions
    that *cannot* be declared free-hand, without their headers.

    By the way, both programs exhibit implementation-defined
    behavior: The "execution was here" line might or might not
    actually show up on the output, or might show up only in part.
    Always write a '\n' at the end of a text output stream.

    --
    Eric Sosman
    lid
    Eric Sosman, Oct 3, 2009
    #2
    1. Advertising

  3. Frank

    Paul N Guest

    On 3 Oct, 10:17, "io_x" <> wrote:
    > "Frank" <> ha scritto nel messaggionews:...
    > > #include <string.h>
    > > int main(void)
    > > {
    > >  int printf(const char *, ...);

    >
    > in what i know here you say to the linker to find
    > "int printf(const char *, ...);"
    > that could be different from printf in <stdio.h>?


    I think you (io_x) could be making the same mistake here that I did
    when I first learnt C. I thought that printf was "in" stdio.h, ie that
    stdio.h contained the code to do printing. This is not the case.

    Headers, such as stdio.h, contain text. This text can be included into
    your program, and will have the same effect as if you included that
    same text yourself in your program file. In the case of printf,
    stdio.h contains a prototype, so that your program knows how to call
    printf properly, but it doesn't have a clue what printf actually does.

    Somewhere else, for example in a file called something.lib, there is
    the actual machine code for printf, and when you link the program the
    linker will find this and do the right thing with it, which will
    normally involve copying the code into your executable.

    My first compiler had six different .LIB files, but this wasn't so
    that each only covered some of the functions, the way that .h files
    do. They were because the computer had a choice of six different
    "memory models" which each required slightly different versions of the
    functions. Each .LIB file contained all of the functions.

    Hope that helps.
    Paul.
    Paul N, Oct 3, 2009
    #3
  4. Frank

    Frank Guest

    On Oct 2, 8:15 pm, Eric Sosman <> wrote:
    > Frank wrote:
    > > I seem to be interested in places where C and fortran are different.

    >
    >      I seem to hope the seeming resembles reality.


    OT reminds of Poe:

    And I hold within my hand
    Grains of the golden sand-
    How few! yet how they creep
    Through my fingers to the deep,
    While I weep- while I weep!
    O God! can I not grasp
    Them with a tighter clasp?
    O God! can I not save
    One from the pitiless wave?
    Is all that we see or seem
    But a dream within a dream?
    >
    >
    >
    > > An example is:
    > > #include <stdio.h>
    > > #include <string.h>
    > > int main() {
    > >    char s[10];
    > >    strcpy(s,"abcdefg");
    > >    strchr(s,'c')[1]='x';
    > >    printf("%s\n",s);
    > >    printf ("execution was here");
    > >    return 0;
    > > }

    >
    > > Can someone say with clarity exactly what happens in the this line:
    > >    strchr(s,'c')[1]='x';
    > > I think it's called array subscripting.  Can someone post an example
    > > of useful code that uses this feature?

    >
    >      There are two things about C you need to know to make sense
    > of this.
    >
    >      The first is sometimes called The Rule: In most contexts
    > (all but two), writing the name of an array in an expression is
    > the same as writing a pointer to the array's first element.
    > That's why the strcpy() and strchr() and printf() calls' use of
    > the array name s is the same as writing &s[0], a pointer to the
    > zero'th element of the array s.
    >
    >      The second is that the indexing operator [] is *defined*
    > in terms of arithmetic on pointers: arr[j] means *(arr+j).  This
    > causes giggles among immature schoolchildren when they suddenly
    > realize that addition is commutative, so *(arr+j) is the same as
    > *(j+arr), which is the same as j[arr].  Tee hee, snicker.
    >
    >      Since indexing is defined in terms of pointer arithmetic,
    > you don't need to do it on an actual array: You can do it with
    > any pointer and any integer (as long as the result is in range).
    > So arr[j] is legal, but so is p[j] when p is a pointer (or when
    > p is an integer and j is a pointer, tee hee, snicker).  Apply
    > The Rule: p[j] means *(p+j).  This use of the same notation with
    > both arrays and pointers is sometimes referred to as "equivalence
    > of pointers and arrays," which is slightly misleading because
    > they are not entirely equivalent.  (Examine the values of
    > sizeof(s) and sizeof(&s[0]) to see one inequivalence.)
    >
    >      Okay, now you've got what you need to understand the line
    > that puzzles you.  strchr() returns a pointer to char, a char*.
    > By The Rule, strchr(s,'c')[1] means *(strchr(s,'c')+1).  As long
    > as strchr() doesn't return NULL (which it doesn't in your case),
    > the addition inside the parentheses is valid (it is *not* valid
    > to add or subtract from a NULL-valued pointer).  So: strchr(s,'c')
    > returns a pointer to the 'c' at the [2] position in s, adding 1
    > produces a pointer to one place further along -- to the [3] spot
    > in s, where the 'd' resides, and then you store 'x' in that spot.


    Ok. Thanks for your response, Eric. I struggle with this every time
    I take up C again (but less and less). It really me understand to
    have someone "talk through" an idiom.
    > > Another thing we don't have are variadic functions.  This was
    > > particularly hard to understand from the K&R material, where I came
    > > away from it thinking the ellipses were added by the book as opposed
    > > to a language token.

    >
    > > #include <string.h>
    > > int main(void)
    > > {
    > >   int printf(const char *, ...);
    > >   char s[10];
    > >   strcpy(s,"abcdefg");
    > >   strchr(s,'c')[1]='x';
    > >   printf("%s\n",s);
    > >   printf ("execution was here");
    > >   return 0;
    > > }
    > > How is this program different from the first?

    >
    >      It's sillier.  The free-hand declaration of printf() is
    > correct and legal (in C99 it is not quite perfect, but still
    > legal as far as I know), but dumb.  Many functions from the
    > Standard library *can* be declared free-hand, but it's silly
    > to do so.  Some can be so declared and the program will work,
    > but you may find that it runs slower than if you'd included
    > the proper header.  And there are several library functions
    > that *cannot* be declared free-hand, without their headers.


    Which ones?
    >
    >      By the way, both programs exhibit implementation-defined
    > behavior: The "execution was here" line might or might not
    > actually show up on the output, or might show up only in part.
    > Always write a '\n' at the end of a text output stream.


    Right. These prototypes are also very implementation-specific, so in
    general, you'd want the the prototype that the vendor thinks you
    need. Is everything here kosher:

    #include <string.h>
    #include <stdlib.h>
    int printf(const char *, ...);
    void print_it(char *);
    int main(void)
    {


    char * p;

    p = malloc(100);
    strcpy(p, "ABQ Balloon Fest today");

    print_it( p );
    free(p);

    return 0;
    }
    Frank, Oct 3, 2009
    #4
  5. Frank

    Frank Guest

    On Oct 3, 9:01 am, Paul N <> wrote:
    > On 3 Oct, 10:17, "io_x" <> wrote:
    >
    > > "Frank" <> ha scritto nel messaggionews:...
    > > > #include <string.h>
    > > > int main(void)
    > > > {
    > > >  int printf(const char *, ...);

    >
    > > in what i know here you say to the linker to find
    > > "int printf(const char *, ...);"
    > > that could be different from printf in <stdio.h>?

    >
    > I think you (io_x) could be making the same mistake here that I did
    > when I first learnt C. I thought that printf was "in" stdio.h, ie that
    > stdio.h contained the code to do printing. This is not the case.
    >
    > Headers, such as stdio.h, contain text. This text can be included into
    > your program, and will have the same effect as if you included that
    > same text yourself in your program file. In the case of printf,
    > stdio.h contains a prototype, so that your program knows how to call
    > printf properly, but it doesn't have a clue what printf actually does.
    >
    > Somewhere else, for example in a file called something.lib, there is
    > the actual machine code for printf, and when you link the program the
    > linker will find this and do the right thing with it, which will
    > normally involve copying the code into your executable.
    >
    > My first compiler had six different .LIB files, but this wasn't so
    > that each only covered some of the functions, the way that .h files
    > do. They were because the computer had a choice of six different
    > "memory models" which each required slightly different versions of the
    > functions. Each .LIB file contained all of the functions.
    >
    > Hope that helps.
    > Paul.


    It helps me, Paul :) I think what you're getting at here is how the
    machine executes a library function and that what you're saying is
    that stdio.h is long gone by this point and that the linker knew where
    to find the correctly-prototyped function and paste in the code.

    I think io_x was getting at this case:


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

    int main(void)
    {


    char * p;

    p = malloc(100);
    strcpy(p, "ABQ Balloon Fest today");

    printf( p );
    free(p);

    return 0;
    }


    int printf(char * r, ...)
    {
    printf ("in function\n");
    printf("%s\n", r);
    }

    I don't know what happens here during compilation or execution.
    Frank, Oct 3, 2009
    #5
  6. Frank

    Frank Guest

    On Oct 3, 10:42 am, Frank <> wrote:

    > I don't know what happens here during compilation or execution.


    I meant with stdio.h included. It draws errors from my
    implementation:


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

    int main(void)
    {

    char * p;

    p = malloc(100);
    strcpy(p, "ABQ Balloon Fest today");

    printf( p );
    free(p);

    return 0;

    }

    int printf(char * r, ...)
    {
    printf ("in function\n");
    printf("%s\n", r);

    }

    Wedit output window build: Sat Oct 03 11:56:39 2009
    Error c:\lcc\source\nick2.c: 23 redefinition of 'printf'
    Error c:\lcc\source\nick2.c: 5 Previous definition of 'printf' here
    Warning c:\lcc\source\nick2.c: 27 missing return value
    Compilation + link time:0.0 sec, Return code: 1
    Frank, Oct 3, 2009
    #6
  7. Frank

    Eric Sosman Guest

    Frank wrote:
    > On Oct 2, 8:15 pm, Eric Sosman <> wrote:
    >> [...] And there are several library functions
    >> that *cannot* be declared free-hand, without their headers.

    >
    > Which ones?


    This would be a good time for you to review the Standard
    library. It's grown a good deal with C99, but even in the C90
    version you should be able to find several examples. Why don't
    you just start trying to write free-hand declarations for all
    the library functions you can think of, no headers allowed, and
    see how far you get before running into a snag?

    > Right. These prototypes are also very implementation-specific, so in
    > general, you'd want the the prototype that the vendor thinks you
    > need.


    No, the prototypes are as dictated by the Standard, and
    cannot be implementation-specific (aside from trivial matters
    like names of function parameters, harmless typedef aliases,
    and so on). There may be implementation-specific "magic"
    accompanying the prototypes, living elsewhere in the declarations
    or in accompanying macros and such. But the prototypes themselves
    are inviolate.

    --
    Eric Sosman
    lid
    Eric Sosman, Oct 3, 2009
    #7
  8. Frank

    Frank Guest

    On Oct 3, 12:32 pm, Eric Sosman <> wrote:
    > Frank wrote:
    > > On Oct 2, 8:15 pm, Eric Sosman <> wrote:
    > >> [...] And there are several library functions
    > >> that *cannot* be declared free-hand, without their headers.

    >
    > > Which ones?

    >
    >      This would be a good time for you to review the Standard
    > library.  It's grown a good deal with C99, but even in the C90
    > version you should be able to find several examples.  Why don't
    > you just start trying to write free-hand declarations for all
    > the library functions you can think of, no headers allowed, and
    > see how far you get before running into a snag?


    That might be a good way to test whether you *really* know these
    functions. I can say with confidence that I do not. The only
    reference to the Standard Library in Unleashed is the book of the same
    name by PJ Plauger. Any opinions on this book?

    >
    > > Right. These prototypes are also very implementation-specific, so in
    > > general, you'd want the the prototype that the vendor thinks you
    > > need.

    >
    >      No, the prototypes are as dictated by the Standard, and
    > cannot be implementation-specific (aside from trivial matters
    > like names of function parameters, harmless typedef aliases,
    > and so on).  There may be implementation-specific "magic"
    > accompanying the prototypes, living elsewhere in the declarations
    > or in accompanying macros and such.  But the prototypes themselves
    > are inviolate.


    Hmm. I guess the sentiment arose from difference between
    implementations in stdio.h that were #defined.

    int printf(const char * restrict format, ...);
    p. 430, 1256.pdf
    is the Standard way that this is defined. You claim that this is
    essentially
    int printf(const char *, ...);
    Right?
    Frank, Oct 3, 2009
    #8
  9. Frank

    Eric Sosman Guest

    Frank wrote:
    > On Oct 3, 12:32 pm, Eric Sosman <> wrote:
    >> Frank wrote:
    >>> On Oct 2, 8:15 pm, Eric Sosman <> wrote:
    >>>> [...] And there are several library functions
    >>>> that *cannot* be declared free-hand, without their headers.
    >>> Which ones?

    >> This would be a good time for you to review the Standard
    >> library. It's grown a good deal with C99, but even in the C90
    >> version you should be able to find several examples. Why don't
    >> you just start trying to write free-hand declarations for all
    >> the library functions you can think of, no headers allowed, and
    >> see how far you get before running into a snag?

    >
    > That might be a good way to test whether you *really* know these
    > functions. I can say with confidence that I do not.


    I'd say I "know" about fifty percent of the Standard
    library, taking "know" to mean "I never consult a reference
    any more." I "sort of know" another twenty-five percent,
    meaning that I can use the functions most of the time but
    need to crack open a book for corner cases. And there's
    another twenty-five percent that I just plain don't use and
    can't claim familiarity with: Most of the new floating-point
    and complex-variable functions of C99, the wide-character
    functions, and the locale functions come to mind as stuff
    my work simply doesn't involve. Even so, I know they exist
    and would know that cracking a book would make them available
    to me should the need ever arise. (Oh, and bsearch(): I find
    it harder to remember how to call bsearch() than just to write
    the search in open code.)

    > The only
    > reference to the Standard Library in Unleashed is the book of the same
    > name by PJ Plauger. Any opinions on this book?


    If by "this book" you mean PJ Plauger's "The Standard C
    Library," I think it excellent. C90-centered, but as I said
    above most of the C99 additions are foreign to me anyhow.

    If by "this book" you mean "C Unleashed" by a cast of
    thousands, I haven't read it and have no opinion.

    > Hmm. I guess the sentiment arose from difference between
    > implementations in stdio.h that were #defined.


    I don't know what you mean by this.

    > int printf(const char * restrict format, ...);
    > p. 430, 1256.pdf
    > is the Standard way that this is defined. You claim that this is
    > essentially
    > int printf(const char *, ...);
    > Right?


    No, they're different. One names the fixed parameter and
    has the `restrict' qualifier; the other doesn't. I claim that
    the presence of the name makes no difference at all, barring
    things like pre-existing macro definitions named `format'. As
    to whether it's legal to omit the `restrict', I *believe* it is
    but it's more a matter of faith than of reason.

    --
    Eric Sosman
    lid
    Eric Sosman, Oct 4, 2009
    #9
  10. On 4 Oct 2009 at 1:43, Eric Sosman wrote:
    > If by "this book" you mean "C Unleashed" by a cast of
    > thousands, I haven't read it and have no opinion.


    Very delicately put, Eric.

    If you and Frank are interested, I'd advise reading some of the threads
    started by Han from China earlier this year, pointing out some of the
    basic errors in the chapters by Richard Heath Field.
    Antoninus Twink, Oct 4, 2009
    #10
  11. Frank

    Frank Guest

    On Oct 3, 6:43 pm, Eric Sosman <> wrote:
    > Frank wrote:
    > > On Oct 3, 12:32 pm, Eric Sosman <> wrote:
    > >> Frank wrote:
    > >>> On Oct 2, 8:15 pm, Eric Sosman <> wrote:
    > >>>> [...] And there are several library functions
    > >>>> that *cannot* be declared free-hand, without their headers.
    > >>> Which ones?
    > >>      This would be a good time for you to review the Standard
    > >> library.  It's grown a good deal with C99, but even in the C90
    > >> version you should be able to find several examples.  Why don't
    > >> you just start trying to write free-hand declarations for all
    > >> the library functions you can think of, no headers allowed, and
    > >> see how far you get before running into a snag?

    >
    > > That might be a good way to test whether you *really* know these
    > > functions.  I can say with confidence that I do not.

    >
    >      I'd say I "know" about fifty percent of the Standard
    > library, taking "know" to mean "I never consult a reference
    > any more."  I "sort of know" another twenty-five percent,
    > meaning that I can use the functions most of the time but
    > need to crack open a book for corner cases.  And there's
    > another twenty-five percent that I just plain don't use and
    > can't claim familiarity with: Most of the new floating-point
    > and complex-variable functions of C99, the wide-character
    > functions, and the locale functions come to mind as stuff
    > my work simply doesn't involve.  Even so, I know they exist
    > and would know that cracking a book would make them available
    > to me should the need ever arise.  (Oh, and bsearch(): I find
    > it harder to remember how to call bsearch() than just to write
    > the search in open code.)
    >
    > > The only
    > > reference to the Standard Library in Unleashed is the book of the same
    > > name by PJ Plauger.  Any opinions on this book?

    >
    >      If by "this book" you mean PJ Plauger's "The Standard C
    > Library," I think it excellent.  C90-centered, but as I said
    > above most of the C99 additions are foreign to me anyhow.


    What version does it have to be? I can pay between 7 and 54 dollars
    for this on Amazon. I don't want anything that is tragically
    outdated.

    > > Hmm.  I guess the sentiment arose from difference between
    > > implementations in stdio.h that were #defined.

    >
    >      I don't know what you mean by this.


    The #defines are more implementation specific than the function
    prototypes, by necessity.
    >
    > > int printf(const char * restrict format, ...);
    > > p. 430, 1256.pdf
    > > is the Standard way that this is defined.  You claim that this is
    > > essentially
    > >   int printf(const char *, ...);
    > > Right?

    >
    >      No, they're different.  One names the fixed parameter and
    > has the `restrict' qualifier; the other doesn't.  I claim that
    > the presence of the name makes no difference at all, barring
    > things like pre-existing macro definitions named `format'.  As
    > to whether it's legal to omit the `restrict', I *believe* it is
    > but it's more a matter of faith than of reason.


    I wish I knew how to bet on faith versus reason. Apparently, none of
    the functions you referred to in your top-snipped post are in
    stdlib.h:



    #ifndef __stdlib_h__
    #define __stdlib_h__
    #include <stddef.h>
    #include <_syslist.h>
    #define MB_CUR_MAX 2
    #define _MAX_PATH 260
    #define _MAX_FNAME 256
    #define _MAX_EXT 256
    #define _MAX_DRIVE 3
    #define _MAX_DIR 256
    #undef RAND_MAX
    #define RAND_MAX 0x7FFF
    typedef struct {
    int quot; /* quotient */
    int rem; /* remainder */
    } div_t;

    typedef struct {
    long quot; /* quotient */
    long rem; /* remainder */
    } ldiv_t;
    typedef struct {
    long long quot;
    long long rem;
    } lldiv_t;
    #undef NULL
    #define NULL ((void *)0)
    #ifndef _WCHAR_T_DEFINED
    typedef unsigned short wchar_t;
    #define _WCHAR_T_DEFINED
    #endif
    #ifndef EXIT_FAILURE
    #define EXIT_FAILURE 1
    #define EXIT_SUCCESS 0
    #endif

    void abort(void);
    int abs(int);
    long long llabs(long long);
    int atexit(void (*_func)(void));
    double atof(const char *);
    int atoi(const char *);
    char *itoa(int,char *,int);
    char *ltoa(long,char *,int);
    void * bsearch(const void * _key,const void * _base, size_t _nmemb,
    size_t _size,
    int (*_compar)(const void *,const void *));
    void * calloc(size_t _nmemb, size_t _size);
    #if __LCCOPTIMLEVEL > 0
    inline div_t __declspec(naked) div(int a,int b)
    {
    _asm("\tmovl\t(%esp),%eax");
    _asm("\tmovl\t4(%esp),%ecx");
    _asm("\tcdq");
    _asm("\tidivl\t%ecx");
    }
    #else
    div_t div(int _numer, int _denom);
    #endif
    void exit(int _status);
    void _exit(int status);
    #define _Exit _exit
    void free(void *);


    double strtod(const char *restrict nptr,char ** restrict endptr);
    long double strtold(const char *restrict nptr,char ** restrict
    endptr);
    float strtof(const char *restrict nptr,char ** restrict endptr);
    char * getenv(const char *_string);
    long labs(long);
    ldiv_t ldiv(long _numer, long _denom);
    lldiv_t lldiv(long long numer,long long denom);
    void * malloc(size_t _size);
    void qsort(void * _base, size_t _nmemb, size_t _size, int(*_compar)
    (const void *, const void *));
    int rand(void);
    void * realloc(void * _r, size_t _size);
    void srand(unsigned _seed);
    double strtod(const char *_n, char **_endvoid);
    long double strtold(const char *,char **);
    long long strtoll(const char *,char **,int);
    unsigned long long strtoull(const char *,char **,int);
    long strtol(const char *_n, char **_endvoid, int _base);
    unsigned long strtoul(const char *_n, char **_end, int _base);
    int system(const char *_string);
    int putenv(const char *_string);
    char * _gcvt(double,int,char *);
    char * _fcvt(double,int,int *,int *);
    char * ecvt(double,int,int *,int *);
    int mbstowcs(wchar_t *,char *,size_t);
    size_t wcstombs( char *mbstr, const wchar_t *wcstr, size_t count );
    int mblen(char *,size_t);
    int mbstrlen(char *s);
    long atol(char *_nptr);

    #ifndef __ANSIC__ONLY__
    #include "safelib.h"

    typedef void (*constraint_handler_t)( const char * restrict msg, void
    * restrict ptr, errno_t error);
    double frand(void);
    constraint_handler_t set_constraint_handler_s( constraint_handler_t
    handler);
    constraint_handler_t get_constraint_handler_s( void );
    void abort_handler_s( const char * restrict msg, void * restrict ptr,
    errno_t error);
    void ignore_handler_s( const char * restrict msg, void * restrict ptr,
    errno_t error);
    errno_t getenv_s(size_t * restrict len, char * restrict value, rsize_t
    maxsize, const char * restrict name);
    void *bsearch_s(const void *key, const void *base, rsize_t nmemb,
    rsize_t size, int (*compar)(const void *k, const void *y, void
    *context), void *context);
    errno_t qsort_s(void *base, rsize_t nmemb, rsize_t size, int (*compar)
    (const void *x, const void *y, void *context), void *context);
    errno_t wctomb_s(int * restrict status, char * restrict s, rsize_t
    smax, wchar_t wc);
    errno_t mbstowcs_s(size_t * restrict retval, wchar_t * restrict dst,
    rsize_t dstmax, const char * restrict src, rsize_t len);
    errno_t wcstombs_s(size_t * restrict retval, char * restrict dst,
    rsize_t dstmax, const wchar_t * restrict src, rsize_t len);


    #ifndef max
    #define max(a,b) (((a) > (b)) ? (a) : (b))
    #define min(a,b) (((a) < (b)) ? (a) : (b))
    #endif
    double wtof(const wchar_t *);
    char *_fullpath( char *absPath, const char *relPath, size_t
    maxLength );
    void _makepath(char *path, const char *drive, const char *dir, const
    char *fname, const char *ext );
    void _splitpath(const char*, char*, char*, char*, char*);

    #define _OUT_TO_DEFAULT 0
    #define _OUT_TO_STDERR 1
    #define _OUT_TO_MSGBOX 2
    #define _REPORT_ERRMODE 3

    extern int _sleep(unsigned long);
    #define sleep _sleep
    #define _mbstrlen mbstrlen
    #define CRTAPI1
    #define _fmode *(_imp___fmode_dll)
    extern int _fmode;
    extern char ***_imp___environ_dll;
    #define _environ (*_imp___environ_dll)
    extern unsigned int _osver;
    extern unsigned int *(_imp___osver);
    #define _osver *(_imp___osver)
    extern unsigned int _winmajor;
    extern unsigned int *(_imp___winmajor);
    #define _winmajor *(_imp___winmajor)
    extern unsigned int _winminor;
    extern unsigned int *(_imp___winminor);
    #define _winminor *(_imp___winminor)
    extern unsigned int _winver;
    extern unsigned int *(_imp___winver);
    #define _winver *(_imp___winver)
    void _searchenv(char *,char *,char *);
    wchar_t * _itow (int, wchar_t *, int);
    wchar_t * _ltow (long, wchar_t *, int);
    unsigned short * _ultow (unsigned long, unsigned short *, int);
    double wcstod(const wchar_t *, wchar_t **);
    long wcstol(const wchar_t *, wchar_t **, int);
    int wctomb(char *s,wchar_t wchar);
    unsigned long wcstoul(const wchar_t *, wchar_t **, int);
    wchar_t * _wgetenv(const wchar_t *);
    int _wsystem(const wchar_t *);
    int _wtoi(const wchar_t *);
    long _wtol(const wchar_t *);
    // Contains argv[0]
    extern char * __declspec(dllimport) _pgmptr;
    int _stdcall _lrotl(unsigned long,unsigned int);
    int _stdcall _lrotr(unsigned int,unsigned int);
    char *_i64toa(long long,char *,int);
    char *_ui64toa(unsigned long long,char *,int);
    long long _atoi64(const char *);
    #define atoi64 _atoi64
    char *_ultoa(unsigned long,char *,int);
    unsigned short *_ultow(unsigned long,unsigned short *,int);
    #define ultoa _ultoa
    #define ultow _ultow
    int _stdcall _System(const char *cmd,int nCmdShow);
    #endif
    #endif /* _STDLIB_H_ */



    #include <stdio.h>
    #include <string.h>
    void Usage(char *programName)
    {
    fprintf(stderr,"%s usage:\n",programName);
    /* Modify here to add your usage message when the program is
    * called without arguments */
    }

    /* returns the index of the first argument that is not an option; i.e.
    does not start with a dash or a slash
    */
    int HandleOptions(int argc,char *argv[])
    {
    int i,firstnonoption=0;

    for (i=1; i< argc;i++) {
    if (argv[0] == '/' || argv[0] == '-') {
    switch (argv[1]) {
    /* An argument -? means help is requested */
    case '?':
    Usage(argv[0]);
    break;
    case 'h':
    case 'H':
    if (!stricmp(argv+1,"help")) {
    Usage(argv[0]);
    break;
    }
    /* If the option -h means anything else
    * in your application add code here
    * Note: this falls through to the default
    * to print an "unknow option" message
    */
    /* add your option switches here */
    default:
    fprintf(stderr,"unknown option %s\n",argv);
    break;
    }
    }
    else {
    firstnonoption = i;
    break;
    }
    }
    return firstnonoption;
    }

    int main(int argc,char *argv[])
    {
    if (argc == 1) {
    /* If no arguments we call the Usage routine and exit */
    Usage(argv[0]);
    return 1;
    }
    /* handle the program options */
    HandleOptions(argc,argv);
    /* The code of your application goes here */
    return 0;
    }

    This compiles on lcc.
    Frank, Oct 4, 2009
    #11
  12. Frank

    Frank Guest

    On Oct 4, 3:03 am, Antoninus Twink <> wrote:
    > On  4 Oct 2009 at  1:43, Eric Sosman wrote:
    >
    > >      If by "this book" you mean "C Unleashed" by a cast of
    > > thousands, I haven't read it and have no opinion.

    >
    > Very delicately put, Eric.


    I won't have you bagging on Unleashed on my threads. It is certainly
    a dubious achievement to have set a record on errata.
    >
    > If you and Frank are interested, I'd advise reading some of the threads
    > started by Han from China earlier this year, pointing out some of the
    > basic errors in the chapters by Richard Heath Field.


    What if help if he called himself "Ludwid van der Heide?" What
    happened to Han?
    Frank, Oct 4, 2009
    #12
  13. On 4 Oct, 23:31, Frank <> wrote:
    > On Oct 4, 3:03 am, Antoninus Twink <> wrote:
    > > On  4 Oct 2009 at  1:43, Eric Sosman wrote:


    > > >      If by "this book" you mean "C Unleashed" by a cast of
    > > > thousands, I haven't read it and have no opinion.

    >
    > > Very delicately put, Eric.

    >
    > I won't have you bagging on Unleashed on my threads.  


    what does "bagging" mean?
    In what way is it your thread?


    > It is certainly
    > a dubious achievement to have set a record on errata.


    Is its errata particulary large? Perhaps this reflects some
    diligence on behalf of the errata producer. One way to avoid
    a large errata is simply not to publish one...


    > > If you and Frank are interested, I'd advise reading some of the threads
    > > started by Han from China earlier this year, pointing out some of the
    > > basic errors in the chapters by Richard Heath Field.


    I advise you also read some less biased review before making your mind
    up.
    Try Amazon and ACCU


    > What if help if he called himself "Ludwid van der Heide?"  What
    > happened to Han?


    ? what?
    Nick Keighley, Oct 5, 2009
    #13
  14. Unleashed is an e-book [Was: variadic functions]

    > > > On  4 Oct 2009 at  1:43, Eric Sosman wrote:

    > > > >      If by "this book" you mean "C Unleashed" by a cast of
    > > > > thousands, I haven't read it and have no opinion.


    It appears to be an e-book
    http://www.ebooks.com/ebooks/book_display.asp?IID=334655
    Nick Keighley, Oct 5, 2009
    #14
  15. Frank

    Eric Sosman Guest

    Frank wrote:
    > On Oct 4, 3:03 am, Antoninus Twink <> wrote:
    >> On 4 Oct 2009 at 1:43, Eric Sosman wrote:
    >>
    >>> If by "this book" you mean "C Unleashed" by a cast of
    >>> thousands, I haven't read it and have no opinion.

    >> Very delicately put, Eric.


    As I don't read "Twink," I didn't see this attempt to
    twist my words until Frank quoted it. Lest any doubt arise
    from "Twink's" attempt to count my vote in his column, I have
    not cast a vote at all. "No opinion" means *no* opinion,
    positive, negative, or neutral.

    I do, however, have an opinion about "Twink."

    --
    Eric Sosman
    lid
    Eric Sosman, Oct 5, 2009
    #15
  16. Frank

    Eric Sosman Guest

    Frank wrote:
    > On Oct 3, 6:43 pm, Eric Sosman <> wrote:
    >>
    >> If by "this book" you mean PJ Plauger's "The Standard C
    >> Library," I think it excellent. C90-centered, but as I said
    >> above most of the C99 additions are foreign to me anyhow.

    >
    > What version does it have to be? I can pay between 7 and 54 dollars
    > for this on Amazon. I don't want anything that is tragically
    > outdated.


    Aren't you the one who used the definite pronoun "this" to
    refer to the book? Rather than "a" book or "some book or other?"
    If you didn't have a particular book in mind, you shouldn't have
    used "this."

    As for versions, I have no idea what you consider "tragically
    outdated." My copy is copyrighted 1992. A lot of people I know
    take their daily guidance from a book that has outsold all others
    (or has a reasonable claim to have done so) but is much older.

    > [... big snip ...]
    > This compiles on lcc.


    Maybe I'm dense today (it's been a difficult day), but I don't
    see the relevance of this gobbet of non-portable code.

    --
    Eric Sosman
    lid
    Eric Sosman, Oct 5, 2009
    #16
  17. Frank

    Frank Guest

    On Oct 5, 2:57 pm, Eric Sosman <> wrote:
    > Frank wrote:
    > > On Oct 3, 6:43 pm, Eric Sosman <> wrote:

    >
    > >>      If by "this book" you mean PJ Plauger's "The Standard C
    > >> Library," I think it excellent.  C90-centered, but as I said
    > >> above most of the C99 additions are foreign to me anyhow.

    >
    > > What version does it have to be?  I can pay between 7 and 54 dollars
    > > for this on Amazon.  I don't want anything that is tragically
    > > outdated.

    >
    >      Aren't you the one who used the definite pronoun "this" to
    > refer to the book?  Rather than "a" book or "some book or other?"
    > If you didn't have a particular book in mind, you shouldn't have
    > used "this."
    >
    >      As for versions, I have no idea what you consider "tragically
    > outdated."  My copy is copyrighted 1992.  A lot of people I know
    > take their daily guidance from a book that has outsold all others
    > (or has a reasonable claim to have done so) but is much older.


    I seem to know less about libraries than most programmers, so I'll
    look forward to getting this. All I saw on Amazon was the 1992
    version. I ended up going with one that cost ten bucks and then four
    to ship.

    I think I share with you a complete indifference to wide character
    stuff. It ate a lot of text in H&S V and it all looked the same.
    (There might a hint of racism in this sentiment. I'm still recovering
    as a bigot.)
    > > This compiles on lcc.

    >
    >      Maybe I'm dense today (it's been a difficult day), but I don't
    > see the relevance of this gobbet of non-portable code.


    I thought you said that there existed functions that are different
    than printf() in that you can't duplicate the task of #including the
    appropriate header by writing out the defintion yourself. Lcc's
    stdlib.h seamed to work just as well pasted in globally as opposed to
    #including it.
    Frank, Oct 6, 2009
    #17
  18. On 5 Oct, 22:57, Eric Sosman <> wrote:

    >      As for versions, I have no idea what you consider "tragically
    > outdated."  My copy is copyrighted 1992.  A lot of people I know
    > take their daily guidance from a book that has outsold all others
    > (or has a reasonable claim to have done so) but is much older.


    Mao's Little Red Book tell you to program in C?!


    "It is well known that when you do anything, unless you understand
    its actual circumstances, its nature and its relations to other
    things,
    you will not know the laws governing it, or know how to do it, or be
    able
    to do it well."

    "Problems of Strategy in China's Revolutionary War" 1936
    Nick Keighley, Oct 6, 2009
    #18
  19. On 6 Oct, 05:42, Frank <> wrote:
    > On Oct 5, 2:57 pm, Eric Sosman <> wrote:
    > > Frank wrote:
    > > > On Oct 3, 6:43 pm, Eric Sosman <> wrote:



    > > >>      If by "this book" you mean PJ Plauger's "The Standard C
    > > >> Library," I think it excellent.  C90-centered, but as I said
    > > >> above most of the C99 additions are foreign to me anyhow.

    >
    > > > What version does it have to be?  I can pay between 7 and 54 dollars
    > > > for this on Amazon.  I don't want anything that is tragically
    > > > outdated.


    <snip>

    > I seem to know less about libraries than most programmers, so I'll
    > look forward to getting this.


    Plauger's book? Excellent book. By the time you've ploughed throgh
    that you'll know a lot about the standard C library. For reference
    I use Harbison & Steel or just google it.

    <snip>

    > > > This compiles on lcc.

    >
    > >      Maybe I'm dense today (it's been a difficult day), but I don't
    > > see the relevance of this gobbet of non-portable code.

    >
    > I thought you said that there existed functions that are different
    > than printf() in that you can't duplicate the task of #including the
    > appropriate header by writing out the defintion yourself.  



    I haven't a clue what that means. What are "function that are
    different
    than [sic] printf()"? What does "can't duplicate the task of
    #including the
    appropriate header by writing out the defintion yourself" mean? For
    any
    standard library function you can write out the prototype yourself
    rather than including the header. This is tedious and error prone
    so why would you do that?


    > Lcc's
    > stdlib.h seamed to work just as well pasted in globally as opposed to
    > #including it.


    that's what #include does. Why would you do that?

    Really. You seem to be hunting for weird ways to do things when the
    standard
    ways work fine. Perhaps Plauger will help you.
    Nick Keighley, Oct 6, 2009
    #19
  20. Frank

    Eric Sosman Guest

    Frank wrote:
    > On Oct 5, 2:57 pm, Eric Sosman <> wrote:
    >> Frank wrote:
    >>> [...]
    >>> This compiles on lcc.

    >> Maybe I'm dense today (it's been a difficult day), but I don't
    >> see the relevance of this gobbet of non-portable code.

    >
    > I thought you said that there existed functions that are different
    > than printf() in that you can't duplicate the task of #including the
    > appropriate header by writing out the defintion yourself. Lcc's
    > stdlib.h seamed to work just as well pasted in globally as opposed to
    > #including it.


    Okay; it was the reference to a "list" of functions that
    threw me, because I don't recall seeing a list.

    The Standard library contains some functions that cannot
    be correctly declared "free-hand," that is, without their
    Standard headers. It also contains functions that *can* be
    so declared, although it's silly to do so.

    The code you showed seemed to be mostly a copy-and-paste
    of some implementation's <stdlib.h>, and I guess you consider
    that a "free-hand" declaration of the contained functions. For
    some -- atof(), for example -- the declaration is just fine and
    you could (if in a silly mood) just write that line in your
    code and buzz merrily along. But for many, the declaration is
    specific to the implementation at hand, and would not work with
    others; you'll have written a declaration of Frobozz Magic C's
    version of ldiv(), not of Standard C's ldiv().

    Well, actually, it's not the declaration of ldiv() itself
    that's the problem -- but what about ldiv()'s result? You know
    that it returns a struct ldiv_t, but where can you find that
    struct type declared? A struct ldiv_t is quite likely arranged
    in a way that's convenient to the hardware, and if you moved
    your program to different hardware the arrangement would differ.
    Claim: The only way to get a struct ldiv_t declaration that
    works everywhere is to include <stdlib.h> and let the header
    tell you about the local customs.

    Then there's rand() -- easy enough to declare portably, but
    what will you do if you need the value of RAND_MAX? And it's
    easy to write a portable declaration of exit(), and you could
    avoid EXIT_SUCCESS by always using zero, but what if you need
    the value of EXIT_FAILURE? How will you write a declaration of
    malloc(), without knowing what size_t is? (In this case you
    could cheat by including one of the other headers that defines
    size_t and then writing your malloc() declaration without using
    <stdlib.h> itself, but that's a subterfuge.)

    There: I've shown you a few <stdlib.h> functions that cannot
    be properly declared without <stdlib.h>, and a few that can be
    declared but can't be used to their fullest without it. You will
    find other similar examples in other Standard headers -- and some
    of those functions are not in the least bit esoteric or odd, but
    are functions you encounter every day.

    --
    Eric Sosman
    lid
    Eric Sosman, Oct 6, 2009
    #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. Loony

    variadic functions

    Loony, Sep 12, 2003, in forum: C++
    Replies:
    2
    Views:
    355
    Kevin Goodsell
    Sep 12, 2003
  2. Colin Walters
    Replies:
    2
    Views:
    509
    Ben Pfaff
    Feb 13, 2004
  3. Ross A. Finlayson
    Replies:
    19
    Views:
    583
    Keith Thompson
    Mar 10, 2005
  4. Replies:
    2
    Views:
    334
    Dave Thompson
    Feb 27, 2006
  5. Replies:
    5
    Views:
    354
Loading...

Share This Page