#145 allow function declarations within a function


it would be nice if SDCC allowed functions to be
declared within a function.

"Other languanges may have had this strange feature for
more than twenty years but I never used it and I
frankly do not care!"

Have a look at printf_large.c:
There are (and there have to be) about 20 occurrences of

output_char (some_char, p);

within the code. They compile to 35 byte in model
mcs51-small (...) each. A function call to a locally
declared function would have come at a cost 5 or 6 byte.

So this printf could have been more than 500 bytes smaller!

gcc would compile this code snippet without complaints:
extern void otherfunc(char a, int b);

int prntf(int q, char a, char b, char c)
int charsOutputtet = 0;

void pc(unsigned char c)
otherfunc(c, q);


return charsOutputtet;


  • Borut Ražem

    Borut Ražem - 2007-01-16

    Logged In: YES
    Originator: NO

    This is a non standard compliant gcc extension and I believe it is not often used because it is not portable to other compilers.

    What about:
    extern void otherfunc(char a, int b);

    static int charsOutputtet = 0;

    static void pc(unsigned char c, int q)
    otherfunc(c, q);

    int prntf(int q, char a, char b, char c)
    pc('a', q);
    pc(b, q);
    pc('0'+c%10, q);

    return charsOutputtet;

  • Maarten Brock

    Maarten Brock - 2007-01-16

    Logged In: YES
    Originator: NO

    I'm with Borut. I don't like this extension.

    And I don't see how declaring a function within another function creates smaller code than when it's outside. What are the assumptions/optimizations you can make based on this?

  • Frieder Ferlemann

    Logged In: YES
    Originator: YES

    Hello Borut and Maarten,

    yes that would work.
    And the solution Maarten has implemented for
    printf_large.c is very nice and compact.

    So my example is probably not a good example any more.

    But I'd see a few drawbacks versus declaring a function
    within a function:

    a) charsOutputtet is visible on a per file basis.
    - this means that if file length n increases
    then the propability of name clashes rises
    much more quickly than n. (Propably n*n)
    Not a problem with embedded programming but
    not nice for a language definition.
    That this can be a problem would be easier
    to see if the variable in question would
    be a counter variable named "i" (and you'd
    need array[butterfly(i)] and bitshuffle(i)).

    b) charsOutputtet is visible on a per file basis
    - so it would be very hard to assign to a
    a register (or into an overlayable segment).
    If it could have been local to function prntf()
    one could assume the function pc() shares
    the same overlay segment as prntf().
    Well ok. The example given here is against
    me as there also is otherfunc())

    c) charsOutputtet is visible on a per file basis
    - so it's not clear by design which function
    should "own" charsOutputtet and in which context
    charsOutputtet is valid.
    If you are new to a project and ask: "which
    function should reset charsOutputtet" then you'd
    have to read and understand the complete file.
    Which is not nice and error prone.
    (In fact the complexity of a file typically rises
    more quickly than with its line number n,
    so limitations of the human mind, blablabla...)

    d) static int charsOutputtet; prohibits reentrancy

    Nota bene: I'd also be happy if no-one adresses this
    While I personally consider it outright ugly
    that C does not allow for this it is probably rather
    less a problem for an embedded compiler than a task
    for the C-Standard.
    GCC was perfectly right to offer this non standard
    compliant extension.


Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:

No, thanks