A bad include in C – why static code analysis is needed for modern C/C++ projects

We have already had a long discussion and argument for ‘include’ mechanism in C/C++, no matter good or bad, and this is not my intention here. I am writing this post to show a confusing compiler error we have recently encountered and debugged for some time and trying to make my point – why static code analysis (SCA) is important for modern C/C++ projects. I am not saying compiler’s not good but saying SCA+compiler making the world better!

/home/daveti/Ctest/cCompiler: cat badHeader.h
// A bad header missing ';'
// badHeader.h
typedef struct _boringStruct
{
 int a;
 int b;
 int c;
} BoringStruct

/home/daveti/Ctest/cCompiler: cat useBadHeader.c
#include <stdio.h>
#include "badHeader.h"

int main()
{
 BoringStruct bs;
 bs.a = 1;
 bs.b = 2;
 bs.c = 3;
 printf( "a=%d, b=%d, c=%dn", bs.a, bs.b, bs.c);
 return 0;
}

/home/daveti/Ctest/cCompiler: gcc -o useBadHeader useBadHeader.c
useBadHeader.c:4: syntax error before "int"
useBadHeader.c: In function `main':
useBadHeader.c:6: `BoringStruct' undeclared (first use in this function)
useBadHeader.c:6: (Each undeclared identifier is reported only once
useBadHeader.c:6: for each function it appears in.)
useBadHeader.c:6: parse error before "bs"
useBadHeader.c:7: `bs' undeclared (first use in this function)

/home/daveti/Ctest/cCompiler: gcc -o useBadHeader.E -E useBadHeader.c
/home/daveti/Ctest/cCompiler: cat useBadHeader.E
......
extern void funlockfile (FILE *__stream) ;
# 679 "/usr/include/stdio.h" 3

# 2 "useBadHeader.c" 2
# 1 "badHeader.h" 1


typedef struct _boringStruct
{
 int a;
 int b;
 int c;
} BoringStruct
# 3 "useBadHeader.c" 2

int main()
{
 BoringStruct bs;
 bs.a = 1;
 bs.b = 2;
 bs.c = 3;
 printf( "a=%d, b=%d, c=%dn", bs.a, bs.b, bs.c);
 return 0;
}

/home/daveti/Ctest/cCompiler: cp useBadHeader.E useBadHeader.c
/home/daveti/Ctest/cCompiler: gcc -o useBadHeader useBadHeader.c
useBadHeader.c:4: syntax error before "int"
useBadHeader.c: In function `main':
useBadHeader.c:6: `BoringStruct' undeclared (first use in this function)
useBadHeader.c:6: (Each undeclared identifier is reported only once
useBadHeader.c:6: for each function it appears in.)
useBadHeader.c:6: parse error before "bs"
useBadHeader.c:7: `bs' undeclared (first use in this function)



/home/daveti/Ctest/cCompiler: cat useBadHeader_hack.c
#include <stdio.h>
#include "badHeader.h"

/* Hack */
;

int main()
{
 BoringStruct bs;
 bs.a = 1;
 bs.b = 2;
 bs.c = 3;
 printf( "a=%d, b=%d, c=%dn", bs.a, bs.b, bs.c);
 return 0;
}

/home/daveti/Ctest/cCompiler: gcc -o useBadHeader_hack useBadHeader_hack.c
/home/daveti/Ctest/cCompiler: ./useBadHeader_hack
a=1, b=2, c=3

/home/daveti/Ctest/cCompiler: gcc -o useBadHeader_hack.E -E useBadHeader_hack.c
/home/daveti/Ctest/cCompiler: cat useBadHeader_hack.E
......
extern void funlockfile (FILE *__stream) ;
# 679 "/usr/include/stdio.h" 3

# 2 "useBadHeader_hack.c" 2
# 1 "badHeader.h" 1


typedef struct _boringStruct
{
 int a;
 int b;
 int c;
} BoringStruct
# 3 "useBadHeader_hack.c" 2


;

int main()
{
 BoringStruct bs;
 bs.a = 1;
 bs.b = 2;
 bs.c = 3;
 printf( "a=%d, b=%d, c=%dn", bs.a, bs.b, bs.c);
 return 0;
}



[root@localhost cCompiler]# ll
total 32
drwxr-xr-x 2 root root 4096 May 29 01:09 .
drwxr-xr-x 3 root root 4096 May 29 01:06 ..
-rw-r--r-- 1 root root  134 May 29 01:07 badHeader.h
-rw-r--r-- 1 root root  212 May 29 01:09 useBadHeader.c
[root@localhost cCompiler]# splint *
Splint 3.1.1 --- 19 Jul 2006

badHeader.h:9:1: Parse Error. (For help on parse errors, see splint -help
 parseerrors.)
*** Cannot continue.
[root@localhost cCompiler]#

About daveti

Interested in kernel hacking, compilers, machine learning and guitars.
This entry was posted in Programming, Static Code Analysis, Stuff about Compiler and tagged , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.