Tag Archives: gcc

Compile time assertion

So, what is an assertion? According to gnu.org :

Its a statement in a program that a condition is true at this point in the program. Useful for reasoning about how a program is supposed to behave.

That is – assertions are predicates (or expressions that result in true/false) that programmers add at various places in the code to convey that the specified conditions must be true for the program to continue & execute normally. Assertions can be used to state the precondition – a condition that must hold true before the execution enters a particular code fragment, or postcondition – a condition that must hold true after the execution of a particular code fragment that it follows. These checks would help in early detection of a problem, which might become tricky to detect otherwise.

Assertions mostly work at either compilation time or execution time. While an assertion failure at execution time can abort a running process (in order to avoid a potential catastrophe), the assertion at compile time would cause the build (compilation) itself to fail. Both have their own advantages. Runtime assertions are widely used in C/C++ programs using assert macro. They are checked during the program execution and in case of assertion failure a signal is raised to abort the program. On the other hand compile-time assertions (the subject of this article) work during compilation phase, failure of which results in termination of compilation.

The predicate in compile-time assertion is normally an expression around compile-time constants. They are usually pre-processor macros that inject syntactically invalid code in the program in case of predicate failure & hence the compilation fails.

Lets understand this by taking an example from MySQL code :

In case the expression – expr – evaluates to false, the above macro would create a character array of an invalid size (-1) which would terminate the compilation. Also note that compilation error like ‘redeclaration error’ can be avoided as the array is defined within a do-while loop, opening up the possibility of it being used at multiple places even inside a function or block.

compile_time_assert(sizeof (some_struct) == 12); // sizeof is a compile-time operator.

C11/C++11 standards have added support for compile-time assertions aka ‘static assertions’ by introducing a new keyword static_assert:

static_assert (constant-expression, error-message);
...
  static_assert(sizeof (int) == 8, "A deliberate static assertion..");
..

$ g++ -std=c++0x static_assert.cpp 
static_assert.cpp: In function ‘int main()’:
static_assert.cpp:3:3: error: static assertion failed: "A deliberate static assertion.."

P.S. Here I intentionally omitted an important preprocessor directive #error which can be used to define assertions during preprocessing stage.

Building a MySQL client program on Linux

Building a C program (client) to connect to MySQL server is simple, but at times it can become a little problematic for a newbie to find all the necessary dependencies (includes/libs). The best option that I would recommend is to use the mysql_config script that comes bundled with the MySQL distribution. This shell script when executed with some options, would print all necessary compiler options/flags/switches required to build a MySQL client program. Lets see it in action!

/**
  @file client_version.c
  Display the client version.
*/

#include 
#include                               /* All public MySQL APIs */

int main()
{
    printf("MySQL client version: %s\n", mysql_get_client_info());
    return 0;
}

# mysql_config's output
> .../bin/mysql_config --cflags --libs
-I/path..to../include  -fPIC -g -fabi-version=2 -fno-omit-frame-pointer -fno-strict-aliasing
-L/path..to../lib -lmysqlclient -lpthread -lm -lrt -ldl

# and now pass it down to the compiler..
> gcc client_version.c `/home/nirbhay/project/repo/bld/trunk/bld/bin/mysql_config --cflags --libs`
.. done

> ./a.out 
MySQL client version: 5.7.2-m12

# whoa.. that worked!

Sometimes, the generated binary would complain of missing shared object file. It can be solved by setting up LD_LIBRARY_PATH to the lib directory containing libmysqlclient.so.NN file.

> ./a.out 
./a.out: error while loading shared libraries: libmysqlclient.so.18: cannot open shared object file: No such file or directory
nirbhay@Nirbhay-lenovo:~/project/sandbox/mysql$ ldd a.out 
	linux-vdso.so.1 =>  (0x00007fffce1ee000)
	libmysqlclient.so.18 => not found
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fca652e6000)
	/lib64/ld-linux-x86-64.so.2 (0x00007fca656a3000)

LD_LIBRARY_PATH=/path..to../lib ./a.out
MySQL client version: 5.7.2-m12

gcc : undefined reference error

A very common compiler error when we try to compile a C++ program using gcc on Linux.

$ gcc new.cc 
/tmp/cccP8Jve.o: In function `main':
new.cc:(.text+0xe): undefined reference to `operator new[](unsigned long)'
new.cc:(.text+0x1c): undefined reference to `std::cout'
...

Fix :

(a) Use g++ : g++ new.cc

(b) gcc -lstdc++ new.cc