User Tools

Site Tools


info:c

C/C++

See also C++ Libraries

C++ Core Guidelines - how to write "modern" C++

C++ FQA Lite ("Frequently Questioned Answers")

C++ FAQ Lite

Inline arrays

An example:

int lock_order[][3] =
	{
		{ NW, SW, SE }, //NNW
		{ INVALID, INVALID, INVALID }, //NNE
		{ INVALID, INVALID, INVALID }, //WNW
		{ INVALID, INVALID, INVALID }, //NW
		{ INVALID, INVALID, INVALID }, //NE
		{ NE, NW, SW }, //ENE
		{ SW, SE, NE }, //WSW
		{ INVALID, INVALID, INVALID }, //SW
		{ INVALID, INVALID, INVALID }, //SE
		{ INVALID, INVALID, INVALID }, //ESE
		{ INVALID, INVALID, INVALID }, //SSW
		{ SE, NE, NW }  //SSE
	};

Filling Containers with Boost.Assign

Boost.Assign can be used to statically initialize containers.

C++0x

Apparent in C++0x you can do this:

std::vector<int> v = {1, 2, 3, 4};

(according to http://stackoverflow.com/questions/2236197/c-easiest-way-to-initialize-an-stl-vector-with-hardcoded-elements).

static modifier

Used outside a function (on a global variable or function): makes the variable only visible within the current file. Similar to using an anonymous/unnamed namespace. In C++, the anonymous namespace is preferred.

Within a function: persistent variable.

Tools

I never can seem to remember the names of some of these:

  • nm - list symbols (possibly add "-D" option)
  • objdump
    • objdump -tT to dump symbols
  • ldd - print shared library dependencies
  • strip - strip debugging symbols

UNIX tools for exploring object files

ELF Statifier does something to combine dynamic libraries to make a "pseudo-statically linked" executable file on Linux.

strace

strace <command args...>

Output to file: strace -o <logfile> <command args...>

Connect to running process: strace -p <pid>

Run strace to get a log of system calls from which unhelpful errors may be better diagnosed.

ltrace

lsof

Lists open files (files, sockets).

Could be used e.g. to correlate file descriptor numbers with the output of strace.

C++ Constants

I can't seem to find a definitive reference, but this seems to be the way to go for global, non-class-related constants:

As to the naming: this convention is suggested by the Google C++ Style Guide. In Effective C++ 3rd Ed., Scott Meyers uses camel-case for constants (not all-uppercase), in contrast to the all-uppercase of a #define.

namespace {
    const char* const kDateFormat = "%Y-%m-%d %X";
    const string kDateFormatStr = "%Y-%m-%d %X";
}

Without the namespace (or static), it would be a violation of the One Definition Rule, generating an error if multiple objects (which included the header with the constant) are linked together. Declaring them static may generate an "unused" warning (I believe this is an Eclipse CDT issue).

If related to a class, declare as a static const member variable.

Alternative - constants class/struct (unfortunately this currently requires header and source for non-int types; maybe it will be relaxed in C++ 1x?):

// constants.hpp
// struct members are public by default
struct Constants {
    static const string kDateFormat;
};
// constants.cpp
const string Constants::kDateFormat = "%Y-%m-%d %X";

Some references:

Possible problem with Eclipse

It looks like Eclipse's Find References (right click → References → Project), from either the definition or a usage, finds nothing if the constant is in an unnamed namespace. It's okay if it is declared static, like so:

static const char* const DATE_FORMAT_MIDNIGHT = "%m-%d-%Y 00:00:00";

However, in the "C/C++ Index" view (Window → Show View → Other… → C/C++ → C/C++ Index), the constant shows up, and clicking "Find References" in the right-click menu works.

I thought this might be related to Bug #307736, but it looks like renaming the constant works fine. Before filing a bug, I should probably check to see if it's fixed in CDT 7.0.

Macro Safety

Always put a do/while(0) around macros that are used like functions. See Why are there sometimes meaningless do/while and if/else statements in C/C++ macros?

C++ Style

See Cxx Style.

C++11

Compiler support:

Some features of interest:

Error Handling in C

Some options:

  • Return NULL or -1 on failure (see e.g. CLASS style)
    • No way of returning human-readable error messages
  • Return error codes
    • Can use errno, which should usually be thread-local
    • Need a special error function to translate codes, unless you just use "standard" values
    • No way of returning instance-specific messages (e.g. a line number)
  • Thread-local pointer to a string object to store an error message?
    • With C++11 you can use the thread_local keyword
    • Otherwise, the easiest way to get a thread-local pointer would be to use Boost; requires linking against the Boost.Thread library
  • Some sort of callback function

Things NOT to do in a library:

  • Print anything to console

Some discussion:

To do: find examples of C libraries that use various approaches

Exceptions in C

Backtraces / Stack traces

In many segfault situations, I find it sufficient to use gdb to get a backtrace:

$ gdb --args PROGRAM [ARGUMENTS...]
(gdb) r
... run until SIGSEGV
(gdb) bt

To print a backtrace on-demand, or on segfault / unhandled exception:

Binary Compatibility

Profiling

Troubleshooting

Undefined Reference errors

How do you troubleshoot "undefined reference", in general?

Probably the right library is not being given to the linker, or the name is spelled incorrectly, or something like that.

Translating Mangled C++ Symbols

Sometimes it may help to know exactly which symbol is undefined. The c++filt command will demangle the name. For example:

$ c++filt _Z17GetTimeFromStringPKci
GetTimeFromString(char const*, int)
# or
$ echo _ZN6MatrixC2ERKS_ | c++filt
Matrix::Matrix(Matrix const&)

Note that sometimes it may be necessary to run it twice:

$ c++filt _GLOBAL__I__ZN13PROCESS_EVENT17AOAInitializationEv
global constructors keyed to _ZN13PROCESS_EVENT17AOAInitializationEv
$ c++filt _GLOBAL__I__ZN13PROCESS_EVENT17AOAInitializationEv | c++filt
global constructors keyed to PROCESS_EVENT::AOAInitialization()

undefined reference to pthread_...

Compile with the -pthread option to include the pthreads library.

undefined reference to `_Unwind_Resume'

I seem to be getting it when compiling some stuff on RHEL4. Maybe it has something to do with threads (CONFIG += thread in qmake?), and in the source file I'm using stream stuff from the C++ standard library.

While I still don't understand this a bit, you can compile with -lgcc_s to make it work.

undefined reference to `vtable for ...'

If the class referenced is an Abstract Base Class, make sure all the virtual methods are either defined or made pure virtual.

Segmentation Fault

Function Call

A segmentation fault at a function call may indicate a stack overflow; that is, the stack size has reached the limit.

The stack size limit could be set in the shell (ulimit or limit command), or in a file (/etc/security/limits.conf on RHEL5).

In the disassembly, the fault location looks like this:

mov %eax,(%esp)

That is, it is attempting to write to the stack pointer (esp).

info/c.txt · Last modified: 2017-08-02 20:54 by sam