code generation depending on sequence of comparisons in if statement

Asked by Felix Meier

Depending on the sequencing of comparisons in an if statement, the code generated will be incomplete or correct.

In the function get_element_0, the check for (p_this != NULL) is NOT translated into machine code.
In the function get_element_1, the check for (p_this != NULL) IS translated into machine code.

/*--------------------------------------------------------------------------*/

#define NULL ((void *)0)

typedef struct s struct_t;

struct s
{
  struct_t * p_next;
};

/*--------------------------------------------------------------------------*/

struct_t * get_element_0 (struct_t * p_chain,
                            struct_t * p_element)
{
  struct_t * p_this;

  p_this = p_chain;

  while ((p_this->p_next != p_element) &&
         (p_this != NULL ))
  {
    p_this = p_this->p_next;
  }

  return (p_this);
}

/*--------------------------------------------------------------------------*/

struct_t * get_element_1 (struct_t * p_chain,
                            struct_t * p_element)
{
  struct_t * p_this;

  p_this = p_chain;

  while ((p_this != NULL ) &&
         (p_this->p_next != p_element))
  {
    p_this = p_this->p_next;
  }

  return (p_this);
}

/*--------------------------------------------------------------------------*/

Invoking GCC with the -v option gives

compiling GCC error.c...
COLLECT_GCC=C:\Programs\GCCARM\bin\arm-none-eabi-gcc
Target: arm-none-eabi
Configured with: /home/build/work/GCC-4-9-build/src/gcc/configure --build=i686-linux-gnu --host=i686-w64-mingw32 --target=arm-none-eabi --prefix=/home/build/work/GCC-4-9-build/install-mingw --libexecdir=/home/build/work/GCC-4-9-build/install-mingw/lib --infodir=/home/build/work/GCC-4-9-build/install-mingw/share/doc/gcc-arm-none-eabi/info --mandir=/home/build/work/GCC-4-9-build/install-mingw/share/doc/gcc-arm-none-eabi/man --htmldir=/home/build/work/GCC-4-9-build/install-mingw/share/doc/gcc-arm-none-eabi/html --pdfdir=/home/build/work/GCC-4-9-build/install-mingw/share/doc/gcc-arm-none-eabi/pdf --enable-languages=c,c++ --disable-decimal-float --disable-libffi --disable-libgomp --disable-libmudflap --disable-libquadmath --disable-libssp --disable-libstdcxx-pch --disable-nls --disable-shared --disable-threads --disable-tls --with-gnu-as --with-gnu-ld --with-headers=yes --with-newlib --with-python-dir=share/gcc-arm-none-eabi --with-sysroot=/home/build/work/GCC-4-9-build/install-mingw/arm-none-eabi --with-libiconv-...
Thread model: single
COLLECT_GCC_OPTIONS='-c' '-mcpu=cortex-m4' '-mthumb' '-gdwarf-2' '-MD' '-O' '-mapcs-frame' '-I' './arm' '-I' './beacon' '-I' './common' '-I' './control' '-I' './mmi' '-I' './sensors' '-I' './seos' '-I' './sysdef' '-I' './usb' '-I' './wlink' '-I' 'C:/Programs/Keil/ARM/Pack/Keil/SAM4_DFP/1.4.0/Device/Include/SAM4S' '-I' 'C:/Programs/Keil/ARM/Pack/ARM/CMSIS/4.5.0/CMSIS/Include' '-mcpu=cortex-m4' '-gdwarf-2' '-Os' '-fno-common' '-Wall' '-no-integrated-cpp' '-g' '-mno-unaligned-access' '-v' '-I' 'C:/Users/Meier/BNGSVN/trunk/targets/BNGPT2/RTE' '-I' 'C:/Programs/Keil/ARM/PACK/Keil/SAM4_DFP/1.4.0/Device/Include/SAM4S' '-I' 'C:/Programs/Keil/ARM/CMSIS/Include' '-I' 'C:/Programs/GCCARM/arm-none-eabi/include' '-I' 'C:/Programs/GCCARM/lib/gcc/arm-none-eabi/4.9.3/include' '-I' 'C:/Programs/GCCARM/arm-none-eabi/include/c++/4.9.3' '-I' 'C:/Programs/GCCARM/arm-none-eabi/include/c++/4.9.3/arm-none-eabi' '-D' '__UVISION_VERSION=518' '-D' '__GCC' '-D' '__GCC_VERSION=493' '-D' '__SAM4S8C__' '-D' 'CONTEXT_DEVICE=1' '-D' 'CONTEXT...
 c:/programs/gccarm/bin/../lib/gcc/arm-none-eabi/4.9.3/cc1.exe -E -quiet -v -I ./arm -I ./beacon -I ./common -I ./control -I ./mmi -I ./sensors -I ./seos -I ./sysdef -I ./usb -I ./wlink -I C:/Programs/Keil/ARM/Pack/Keil/SAM4_DFP/1.4.0/Device/Include/SAM4S -I C:/Programs/Keil/ARM/Pack/ARM/CMSIS/4.5.0/CMSIS/Include -I C:/Users/Meier/BNGSVN/trunk/targets/BNGPT2/RTE -I C:/Programs/Keil/ARM/PACK/Keil/SAM4_DFP/1.4.0/Device/Include/SAM4S -I C:/Programs/Keil/ARM/CMSIS/Include -I C:/Programs/GCCARM/arm-none-eabi/include -I C:/Programs/GCCARM/lib/gcc/arm-none-eabi/4.9.3/include -I C:/Programs/GCCARM/arm-none-eabi/include/c++/4.9.3 -I C:/Programs/GCCARM/arm-none-eabi/include/c++/4.9.3/arm-none-eabi -imultilib armv7e-m -iprefix c:\programs\gccarm\bin\../lib/gcc/arm-none-eabi/4.9.3/ -isysroot c:\programs\gccarm\bin\../arm-none-eabi -MD ./arm/obj/gcc error.d -MQ ./arm/obj/gcc error.o -D__USES_INITFINI__ -D __UVISION_VERSION=518 -D __GCC -D __GCC_VERSION=493 -D __SAM4S8C__ -D CONTEXT_DEVICE=1 -D CONTEXT_BDE=0 -D ARM_MATH_CM...
ignoring duplicate directory "c:/programs/gccarm/lib/gcc/../../lib/gcc/arm-none-eabi/4.9.3/include"
ignoring nonexistent directory "c:\programs\gccarm\bin\../arm-none-eabi/home/build/work/GCC-4-9-build/install-mingw/lib/gcc/arm-none-eabi/4.9.3/../../../../include"

Question information

Language:
English Edit question
Status:
Solved
For:
GNU Arm Embedded Toolchain Edit question
Assignee:
No assignee Edit question
Solved by:
Thomas Preud'homme
Solved:
Last query:
Last reply:
Revision history for this message
Best Thomas Preud'homme (thomas-preudhomme) said :
#1

Hi Felix,

 while ((p_this->p_next != p_element) &&
         (p_this != NULL ))

The above is undefined behavior because you dereference p_this before checking if it's NULL. GCC then is free to deduce that p_this is not NULL (otherwise it would be an error to dereference it) and remove the NULL check which it sees as useless.

You should thus invert the order of the tests in that bitwise AND expression.

Best regards

Revision history for this message
Felix Meier (felix-meier-45) said :
#2

Dear Thomas,

Thank you for your answer. It confirms my own
interpretation.