C faq ,ques-2.9,2.18

Discussion in 'C Programming' started by SAHIL MAHLA, May 22, 2014.



    Could you explain the following statements:

    ques 2.9:
    "Structures are often returned from functions in a location pointed to by an extra, compiler-supplied ``hidden'' argument to the function"

    and then in ques 2.18:
    Since structure-valued functions are usually implemented by adding a hidden return pointer (see question 2.9), the generated code for main() tries to accept three arguments, although only two are passed (in this case, by the C start-up code).

    Is there a need of adding an extra argument to the function returning the pointer to structure?

    Thanks in advance
    SAHIL MAHLA, May 22, 2014
    1. Advertisements


    BartC Guest

    The called function presumably needs the extra argument so that it knows
    where to copy the structure it will be returning. This structure will reside
    somewhere in the caller.
    BartC, May 22, 2014
    1. Advertisements


    James Kuyper Guest

    Nothing needs to be done at the C level to deal with such issues; such
    things are entirely the responsibility of the compiler to deal with.

    Thes issues only matter if you're trying to interface with another
    language, such as assembler. Then you may need to know full details
    about precisely how the compiler that you're using handles such hidden
    arguments. The information you collect about such things for one
    compiler could be completely useless when dealing with a different
    compiler, particularly if it targets a different platform.
    James Kuyper, May 22, 2014


    Could you quote a example Bart.

    SAHIL MAHLA, May 22, 2014

    BartC Guest

    Suppose you have a struct 'date', a function 'nextday' which is passed a
    struct by value, and returns another struct by value too. In C it might look
    like this:

    typedef struct {
    int day, month, year;
    } date;

    date nextday(date d) {
    // if (d.day > ....) .... etc

    return d;

    int main (void) {
    date d={25,12,2013},e;
    e = nextday(d);

    Using a hidden parameter, it might be compiled as though it had been written
    like this:

    void nextday(date d, date* $hiddenptr) {
    // if (d.day > ....) .... etc

    *$hiddenptr = d;

    int main (void) {
    date d={25,12,2013},e;
    date $hidden;

    e=$hidden; // or just nextday(d,&e);

    (However I have no idea whether any compilers do it exactly this way. When
    I've had to implement struct-passing in a compiler, I used the stack. Not
    quite as efficient, but I hardly ever passed structs by value so it didn't
    BartC, May 22, 2014


    Appreciate your effort Bart..thanks.
    SAHIL MAHLA, May 22, 2014


    Hi Bart

    But i have a question here, why compiler is not able to provide that implicit compiler generated variable in the case of faq ques 2.18

    SAHIL MAHLA, May 23, 2014

    BartC Guest

    OK, maybe I should have looked at the FAQ first...

    That example is where a missing semicolon leads to a still syntactically
    'correct' but wrong program like this:

    struct {... } main (a,b) { ....}

    (instead of: struct {...}; main(a,b) {...} using an implicit 'int' return
    type for main.)

    So the function 'main' might have an extra third parameter added in addition
    to a and b (which should have types but I haven't bothered).

    The trouble is that the code calling main() is not written in C (or if it
    is, it is compiled without knowledge of your declaration of main()), and is
    passed only the two normal parameters. This will screw up the return

    (I'm not sure why this should happen because main() is a special function
    which takes either 2 or 0 arguments, and returns an int value. Probably some
    compilers at certain warning levels will complain.)
    BartC, May 23, 2014
  9. Here's the code from the question:

    struct list {
    char *item;
    struct list *next;

    /* Here is the main program. */

    main(argc, argv)
    { ... }

    There's a missing semicolon on the struct definition, making the
    compiler think that the struct type is the return type of main.

    The problem is that C's grammar is what I think of as "dense" (I
    don't think that's a technical term, just the way I describe it).
    What I mean by that is that a typo in a C program can easily give
    you something that's still syntactically valid, but has a completely
    different meaning or that triggers a seemingly meaningless error.

    The standard requires main to have a return type of int (or some
    other implementation-defined type, but almost certainly not this
    struct type) -- but violating that requirement, though it's an error,
    is not something a compiler is required to diagnose. The behavior
    is undefined. There's no particular reason for a compiler to make
    it "work", because there is no correct behavior. Making main work
    "correctly" while returning a struct value is not useful, because
    that's not what the person who wrote the code intended to do in
    the first place.

    Incidentally, the above code appears to be very old. Before 1999,
    C permitted a function's return type to be omitted, defaulting
    to int. With the semicolon added to the struct definition,
    the code is valid *only in old versions of C*; a conforming C99
    or later compiler must complain about the missing return type.
    (And the parameter definitions use an obsolescent form as well.)
    Keith Thompson, May 23, 2014

    James Kuyper Guest

    On 05/23/2014 12:06 PM, Keith Thompson wrote:
    The technical term for the property you describe is "low redundancy".
    If you make a small random change to a C source code file, you stand a
    pretty good chance of either leaving the meaning unchanged (mainly as a
    result of adding or deleting redundant white space, possibly in
    comments), or producing code for which a diagnostic is mandatory. You
    could also silently change the meaning, as in this case, and such cases
    are annoyingly common, - but I'm not sure that they are common enough to
    justify calling C a "low redundancy" language.

    I find it nearly impossible to write even a short source code module
    without making several typos, and those typos almost always result in
    diagnostics. Once I get past that phase, I almost never find defects
    caused by typos that silently changed the meaning - the remaining
    defects are almost always the result of my thinking about the code or
    the specifications incorrectly.
    James Kuyper, May 23, 2014
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.