This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
c/4101: gcc 2.95.4 compiles bad code with nested static functions
- To: gcc-gnats at gcc dot gnu dot org
- Subject: c/4101: gcc 2.95.4 compiles bad code with nested static functions
- From: chitty at libero dot it
- Date: 23 Aug 2001 18:25:52 -0000
- Cc: alessandro_amici at telespazio dot it
- Reply-To: chitty at libero dot it
>Number: 4101
>Category: c
>Synopsis: gcc 2.95.4 compiles bad code with nested static functions
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: unassigned
>State: open
>Class: wrong-code
>Submitter-Id: net
>Arrival-Date: Thu Aug 23 11:26:00 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator: Cristiano Milia
>Release: gcc version 2.95.4 20010319 (Debian prerelease)
>Organization:
>Environment:
Linux 2.4.6-mosix #1 SMP i686
>Description:
f2 is a function defined into another function body, and f pointer is declared static in the same scope of f2.
when assigning address of f2 to f, the correct assignment is correctly done ONLY IF the BODY of f2 is defined AFTER the assignment statement.
the result of this wrong address generation is an "illegal instruction" at runtime, when executing (*f)().
the fact is that f is assigned a value that is NOT the actual f2 value.
it seems to me that if f2 is DEFINED before the assignment statement, gcc gets confused about its address, that is not the one f2 had when it was DECLARED.
function_2 can be have an empty body or not, it always happens.
>How-To-Repeat:
/* this must do a certain thing only the 1st time,
but we don't want a check as if (first_time) {do},
so we use a function pointer that the first time
does, the others just returns.
*/
void loop(void)
{
void f1(void);
void f2(void);
static void (*f)(void) = f1;
void f2(void) { } /* this is empty */
void f1(void)
{
/* ... do something */
f=f2; /* the problem is HERE */
}
(*f)(); /* do something only the first time */
}
int main()
{
loop();
loop(); /* second time it crashes! */
}
>Fix:
just put the DEFINITION of f2 AFTER the assignment statement:
void loop(void)
{
void f1(void);
void f2(void);
static void (*f)(void) = f1;
void f1(void)
{
f=f2; /* NOW it correctly assigns the address of f2 */
}
void f2(void) { }
(*f)();
}
>Release-Note:
>Audit-Trail:
>Unformatted: