Hi, I can't understand why doesn't the following piece of code end with segfault while dereferencing a NULL pointer in line 29 but only when compiled with `-fn-delete-null-pointer-checks' and `-02': #include <stdio.h> struct agnx_priv { char demo; }; struct ieee80211_hw { struct agnx_priv *priv; }; struct pci_dev { struct ieee80211_hw* dev; }; struct ieee80211_hw* pci_get_drvdata(struct pci_dev *pdev) { if(!pdev) return NULL; return pdev->dev; } static void agnx_pci_remove (struct pci_dev *pdev) { printf("pdev value: %p\n", pdev); int a = 700; struct ieee80211_hw *dev = pci_get_drvdata(pdev); printf("dev value: %p\n", dev); struct agnx_priv *priv = dev->priv; printf("past the dereferenc: %p\n", dev); if (!dev) return; // This will segfault if the previous if is optimized printf("%c\n", priv->demo); } int main(int argc, char **argv) { // (struct pci_dev *)argv[1] is just to avoid compiler optimisations // =~ NULL if no args are passed. struct pci_dev * pdev = (struct pci_dev *)argv[1]; agnx_pci_remove(pdev); return 0; } $ gcc -O2 -fno-delete-null-pointer-checks POST.c -o POST $ ./POST pdev value: (nil) dev value: (nil) past the dereferenc: (nil) $ gcc -O2 POST.c -o POST $ ./POST pdev value: (nil) dev value: (nil) Segmentation fault $ gcc -fno-delete-null-pointer-checks POST.c -o POST $ ./POST pdev value: (nil) dev value: (nil) Segmentation fault Basically I started reading up on `-fno-delete-null-pointer-checks' option after I learned it's used to compile Linux kernel. I read that in case of kernel there is no segfault when attempting to dereference a NULL pointer but a special handler named kernel oops instead comes in place. This is why one may want to use `-fno-delete-null-pointer-checks' when compiling kernel to make sure that there won't be any NULL checks ignored even after erroneously dereferencing a pointer it before checking with combination with `-O2'. However, in userlands program it's common for a program to crash and emit signal 11. I know that dereferencing a NULL pointer is an UB according to C standard. I am wondering though if anybody can point any technical reasons why doesn't the code I posted result in segfault. What is more strange, it ends with segfault when dereferencing a NULL pointer right away inside main(): int main(int argc, char **argv) { // (struct pci_dev *)argv[1] is just to avoid compiler optimisations // =~ NULL if no args are passed. struct pci_dev * pdev = (struct pci_dev *)argv[1]; printf("pdev value is %p\n", pdev); struct ieee80211_hw *dev = pci_get_drvdata(pdev); printf("before dereferencing\n"); struct agnx_priv *priv = dev->priv; printf("%c\n", priv->demo); agnx_pci_remove(pdev); return 0; } $ gcc -fno-delete-null-pointer-checks POST.c -o POST $ ./POST pdev value: (nil) dev value: (nil) Segmentation fault I spent a couple of hours looking for an explanation but my GCC-fu is too poor. I tried to have fun and write another program on which I could use `-O2 -fno-delete-null-pointer-checks' and see in practice that subsequent NULL checks are ignored after first successful dereferencing but can't write any in which I am able to get past first NULL pointer dereferencing such as this one which when run with parameter 0 already crashes at line 7: #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { int *p = (int *) atoi(argv[1]); int i = *p; if (!p) { printf("exiting\n"); exit(1); } printf("%d\n", i); exit(0); } My OS is Linux Slackware with kernel 3.2.29-smp and GCC version is 4.7.1