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:
http://svn.sourceforge.net/viewcvs.cgi/sdcc/trunk/sdcc/device/lib/printf_large.c?view=markup
There are (and there have to be) about 20 occurrences of
output_char (some_char, p);
charsOutputted++;
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:
--------------8<---------------------------------------
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);
charsOutputtet++;
}
if(a)
pc('a');
if(b)
pc(b);
pc('0'+c%10);
return charsOutputtet;
}
Logged In: YES
user_id=568035
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:
--------------8<---------------------------------------
extern void otherfunc(char a, int b);
static int charsOutputtet = 0;
static void pc(unsigned char c, int q)
{
otherfunc(c, q);
charsOutputtet++;
}
int prntf(int q, char a, char b, char c)
{
if(a)
pc('a', q);
if(b)
pc(b, q);
pc('0'+c%10, q);
return charsOutputtet;
}
Logged In: YES
user_id=888171
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?
Logged In: YES
user_id=589052
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
request.
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.