I have written the following code, but want to know why this program is exhibiting different behavior with compiler optimization
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <pthread.h>
unsigned int counter = 0;
void *thread0_func(void *arg)
{
unsigned int i = 0;
printf("Thread 0\n");
while(1)
{
sleep(3);
counter++;
}
return NULL;
}
void action_handler(int sig_no)
{
printf("SigINT Generated: %d\n",counter);
counter += 1;
}
int main(int argc, char **argv)
{
pthread_t thread_id[2];
struct sigaction sa;
sa.sa_handler = action_handler;
if(sigaction(SIGINT, &sa, NULL))
perror("Cannot Install Sig handler");
if(pthread_create(&thread_id[0], NULL, thread0_func, NULL))
{
perror("Error Creating Thread 0");
}
else
{
}
while(counter == 0);
printf("Counter: %d\n", counter);
// pthread_join(thread_id[0], NULL);
return (0);
}
Under normal compilation condition (without optimization), ie. gcc example.c -o example -pthread
the program works as per the expected logic written i.e. the program waits on the instruction while(counter == 0);
for variable counter
value to become non zero either from thread or from signal handler, then, loop breaks and the program prints the value and exit.
If the code is compiled with gcc -O3 example.c -o example -pthread
, then the program keeps running and incrementing the value from thread as well as whenever signal handler gets executed.
$ ./example
Thread 0
^CSigINT Generated: 4
^CSigINT Generated: 6
^CSigINT Generated: 8
^CSigINT Generated: 9
^CSigINT Generated: 11
^CSigINT Generated: 12
But some people says that this code is not compliant and will produce a UB across different platforms!