ARM Technical Support Knowledge Articles

Why does "armcc -E" preprocessing result in linker undefined symbol error?

Applies to: DS-5, RealView Development Suite (RVDS)

Scenario

When compiling and linking preprocessed C++ sources, linker errors like below can be generated by the linker:

armcc -E test.cpp > pp_test.cpp
armcc pp_test.cpp


Error: L6218E: Undefined symbol std::vector<int*, std::allocator<int*>>::_C_insert_aux(int**, int*const &) (referred from pp_test.o).

where test.cpp #include a header file. This header file #include some C++ template libraries (STL) such as <vector>. Directly compiling/linking test.cpp does not generate this linker error.

The implication of this linker error is that the "armcc -E" preprocessor expands only explicit #include directives.

Answer

The C++ implicit inclusion mechanism relies on the dependency among the C++ header file and other C++ files (files with extensions such as .cxx , .CXX , .C , .cc , .CC , .cpp , and .c). By default, the preprocessing phase of a normal compilation expands all explicit #include header files. In addition, some C++ files such as .cc files would be implicitly added to the end of the translation unit. This mechanism is called implicit inclusion. However, implicit inclusion does not take place when using the "armcc -E" preprocessor. Therefore, if definitions of template entities are defined in a .cc file, "armcc -E" will fail to include such definitions, hence the undefined symbol error when trying to compile the preprocessed source.

A solution to this problem is to use the option --no_implicit_include with -E together when preprocessing the source code. As a result, --no_implicit_include will cause the internal compiler macro __IMPLICIT_INCLUDE to be undefined. Undefining __IMPLICIT_INCLUDE causes _RWSTD_COMPILE_INSTANTIATE to be defined. The required .cc files can then be included to the preprocessed translation unit (see example below). So compiling the preprocessed source can succeed because all required template definitions are in the preprocessed translation unit already.

Example: code snippet in <vector>

#if defined (_RWSTD_COMPILE_INSTANTIATE)
#  include <vector.cc>
#endif

As a side effect of adding --no_implicit_include option to the "armcc -E" preprocessing step, user may find the code and data sizes are bigger. This is understandable because the above mechanism can explicitly include some unused .cc files.

Rate this article

[Bad]
|
|
[Good]
Disagree? Move your mouse over the bar and click

Did you find this article helpful? Yes No

How can we improve this article?

Link to this article
Copyright © 2011 ARM Limited. All rights reserved. External (Open), Non-Confidential