[Bug c/57813] New: Change of global variable ignored
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57813 Bug ID: 57813 Summary: Change of global variable ignored Product: gcc Version: 4.8.0 Status: UNCONFIRMED Severity: major Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: daniel.oertwig at gmail dot com Target: avr51 Created attachment 30450 -- http://gcc.gnu.org/bugzilla/attachment.cgi?id=30450action=edit Source code relating to the problem Hi, I assume this to be a bug in how the compiler optimizes its code. Unfortunately, I don't know enough about how the gcc works to narrow down the source of the problem. If it's me (or my code), please tell me what I am doing wrong. Basically I have a function operating on a global variable. This function calls another function which changes this global variable. But the changed value is not used by the calling function afterwards. Task * Task_getNextReady() { uint8_t priority; if (taskInfo.ready[0]) priority = 0; else if (taskInfo.ready[1]) priority = 1; else if (taskInfo.ready[2]) priority = 2; else if (taskInfo.ready[3]) priority = 3; else if (taskInfo.ready[4]) priority = 4; else if (taskInfo.ready[5]) priority = 5; else if (taskInfo.ready[6]) priority = 6; else priority = 7; // Before call to function: taskInfo.ready[priority] == task6 // After call to function: taskInfo.ready[priority] == task7 // Return value = 10 taskInfo.ready[priority]-wakeTime = Task_enforceTimeslice(priority); // Changed task6-wakeTime = 10 // Unchanged task7-wakeTime // Return value is task7, which is correct. return taskInfo.ready[priority]; } I guess i could solve this by making the variable volatile, but I don't think that this would be correct.
[Bug c/57813] Change of global variable ignored
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57813 --- Comment #1 from Daniel Oertwig daniel.oertwig at gmail dot com --- Created attachment 30451 -- http://gcc.gnu.org/bugzilla/attachment.cgi?id=30451action=edit Disassembly of the relating parts (from *.elf file, i.e. after linking)
[Bug c/57813] Change of global variable ignored
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57813 --- Comment #2 from Daniel Oertwig daniel.oertwig at gmail dot com --- Oh, I am compiling with: CFLAGS := CFLAGS += -Os CFLAGS += -funsigned-char CFLAGS += -funsigned-bitfields CFLAGS += -fpack-struct CFLAGS += -fshort-enums CFLAGS += -ffreestanding CFLAGS += -Wall -Wextra CFLAGS += -Wstrict-prototypes CFLAGS += -Wundef CFLAGS += -Wsign-compare CFLAGS += -std=gnu99 #-std=c99 CFLAGS += -g3 -gdwarf-2 -pg CFLAGS += -fstack-usage LDFLAGS := LDFLAGS += -Wl,--relax using avr-gcc. There are no warnings.
[Bug c/57813] Change of global variable ignored
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57813 Daniel Oertwig daniel.oertwig at gmail dot com changed: What|Removed |Added Status|RESOLVED|UNCONFIRMED Resolution|INVALID |--- --- Comment #4 from Daniel Oertwig daniel.oertwig at gmail dot com --- Task * Task_getNextReady() { uint8_t priority; if (taskInfo.ready[0]) priority = 0; else if (taskInfo.ready[1]) priority = 1; else if (taskInfo.ready[2]) priority = 2; else if (taskInfo.ready[3]) priority = 3; else if (taskInfo.ready[4]) priority = 4; else if (taskInfo.ready[5]) priority = 5; else if (taskInfo.ready[6]) priority = 6; else priority = 7; time_t delay = Task_enforceTimeslice(priority); Task * next = taskInfo.ready[priority]; next-wakeTime = delay; return next; } This code solves the issue, using the correct value of the global variable. Please tell me if I am wrong, but I think this code should be equivalent to the original code. (Task_enforceTimeslice is not declared as pure, I checked just to be sure)
[Bug c/57813] Change of global variable ignored
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57813 --- Comment #5 from Daniel Oertwig daniel.oertwig at gmail dot com --- (In reply to Andrew Pinski from comment #3) taskInfo.ready[priority]-wakeTime = Task_enforceTimeslice(priority); This is the same as: (*taskInfo.ready[priority]).wakeTime = Task_enforceTimeslice(priority); Which means either the compiler can read the value of taskInfo.ready[priority] before or after the function call to Task_enforceTimeslice because there is no sequence point between them. Shouldn't the compiler recognize that enforceTimeslice is altering the global variable?
[Bug c/57813] Change of global variable ignored
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57813 --- Comment #8 from Daniel Oertwig daniel.oertwig at gmail dot com --- Ok, so: Is this behaviour part of the language or a bug in gcc? I could not find any documentation specifying that a sequence point should be inbetween the (side-effect) evaluation of the function call and the (value) evaluation of the assignment.