Initialization in a function declaration

Discussion in 'C Programming' started by John Taylor, Sep 23, 2009.

  1. John Taylor

    John Taylor Guest

    Hello,

    I'm reading the C99 standard. I have a doubt about declarations, in
    particular function declarations. I know it is not possible to put an
    initializer inside a function declaration, but I cannot find the point
    in the standard that forbids it. For example if I try to compile a
    minimal C99 program containing the following declaration:

    int add(int a, int b) = 5;

    I get the following error message:

    error: function ‘add’ is initialized like a variable

    But by applying the BNF syntax description, I can say that "5" is an
    <initializer>, "add(int a, int b)" is a <declarator>, "add(int a, int b)
    = 5" is an <init-declarator>, "int" is a <declaration-specifiers> and so
    "int add(int a, int b) = 5" is a <declaration>.

    What's wrong with my reasoning?

    Thanks.
     
    John Taylor, Sep 23, 2009
    #1
    1. Advertisements

  2. John Taylor

    John Taylor Guest

    Thanks Richard!
     
    John Taylor, Sep 23, 2009
    #2
    1. Advertisements

  3. John Taylor

    bartc Guest

    Even if your reasoning was correct, what would be the meaning of your code
    fragment? That at location 000005 in memory you expect to have a function
    that uses the signature you've declared?
     
    bartc, Sep 23, 2009
    #3
  4. That's a good point, but not really an answer to the question.
    If the standard somehow neglected to forbid

    int add(int a, int b) = 5;

    and yet failed to give it any meaning, that would be a flaw in the
    standard.

    Fortunately, as Richard has pointed out, the standard *does* forbid
    such a declaration (it's a constraint violation, not a syntax error).
     
    Keith Thompson, Sep 23, 2009
    #4
  5. Sure, but that would be a substantial departure from what initializers
    mean in other contexts. The normal expectation would be that

    int add(int a, int b) = 5;

    declares something called "add" and, in effect, assigns the value 5 to
    it.

    A less radical way to do the same thing would be to change the syntax
    for a function-definition from

    function-definition:
    declaration-specifiers declarator declaration-listopt compound-statement

    to

    function-definition:
    declaration-specifiers declarator declaration-listopt statement

    which would allow

    int add(int a, int b) return a+b;

    Not that I'm advocating such a change; it's easy enough to write:

    int add(int a, int b) { return a+b };
     
    Keith Thompson, Sep 23, 2009
    #5
  6. John Taylor

    Alan Curry Guest

    One logical meaning would be "the machine code implementing this function has
    the same bit pattern as the int value 5", like what you'd get if you did
    this:

    int a = 5;
    #define add ((int(*)(int,int))(&a))

    Longer definitions would be done with an array:
    int add(int a, int b) = { 0x7c641a14, 0x4e800020 };

    Consider it a mix of C and its typeless predecessor B, where it would look
    something like this:

    /* untested, don't have a B compiler handy */
    add[] 0x7c641a14, 0x4e800020;
    main()
    {
    auto four;
    four = add(2, 2);
    }
     
    Alan Curry, Sep 23, 2009
    #6
  7. John Taylor

    Phil Carmody Guest

    I'd never even consider backing an arguement for the introduction
    of usage like that into this particular language, but can actually
    see some vague merit in

    //...
    #if !defined(FANCY_ALLOCATOR)
    void* my_malloc(size_t) = malloc;
    #else
    void* my_malloc(size_t n) { void*p; pre(); p=malloc(n); post(); return p; }
    #endif

    Phil
     
    Phil Carmody, Sep 24, 2009
    #7
  8. IIRC, Old Mac OS headers used something similar for inlined
    assembly functions [= { 0xABCD }]. They were typically trap
    instructions to ROM functions. They were often preceeded with
    pragmas declaring parameter and return registers.
     
    Peter Nilsson, Sep 24, 2009
    #8
  9. Ah, but you can already do that by optionally making my_malloc
    a function pointer:

    #if !defined(FANCY_ALLOCATOR)
    void *(*const my_malloc)(size_t) = malloc;
    #else
    void *my_malloc(size_t n) { void *p; pre(); p=malloc(n); post(); return p; }
    #endif
     
    Keith Thompson, Sep 24, 2009
    #9
  10. John Taylor

    Chris Dollin Guest

    Or, historically closer, a BCPL function declaration:

    let add( a, b ) = a + b;

    --
    "The career of Hern VI from its native Acolyte cluster - James Blish
    across the centre of the galaxy made history -- /Earthman, Come Home/
    particularly in the field of instrumentation."

    Hewlett-Packard Limited registered no:
    registered office: Cain Road, Bracknell, Berks RG12 1HN 690597 England
     
    Chris Dollin, Sep 24, 2009
    #10
  11. John Taylor

    Phil Carmody Guest

    That you can. The const mostly addresses the only objection I'd have, too.

    Phil
     
    Phil Carmody, Sep 24, 2009
    #11
  12. Nit: old FORTRAN statement function. The FORTRAN FUNCTION statement is
    the beginning of a (proper, blocked) function (SUBROUTINE similarly).
    FORTRAN doesn't have statements and declarations as disjoint
    grammatical forms, instead it has statements of various types some of
    which are executable and some of which aren't, including declarations.

    And BTW it's still there, although (quite) poor style since F90; it's
    'obsolescent' (often called deprecated) since at least F95 (I no
    longer have F90 to check), but kept in F03 and AIUI F08 (still in
    ballot). Like K&R1 functions obsolescent in C89 but kept in C99.

    At least some BASICs also had (only) similar syntax:
    DEF FNA(X) = (X-10)**2
    IIRC this was in the original Dartmouth BASIC.
     
    David Thompson, Oct 5, 2009
    #12
    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.