Follow Techotopia on Twitter

On-line Guides
All Guides
eBook Store
iOS / Android
Linux for Beginners
Office Productivity
Linux Installation
Linux Security
Linux Utilities
Linux Virtualization
Linux Kernel
System/Network Admin
Scripting Languages
Development Tools
Web Development
GUI Toolkits/Desktop
Mail Systems
Eclipse Documentation

How To Guides
General System Admin
Linux Security
Linux Filesystems
Web Servers
Graphics & Desktop
PC Hardware
Problem Solutions
Privacy Policy




Chapter 6. Line Control

The C preprocessor informs the C compiler of the location in your source code where each token came from. Presently, this is just the file name and line number. All the tokens resulting from macro expansion are reported as having appeared on the line of the source file where the outermost macro was used. We intend to be more accurate in the future.

If you write a program which generates source code, such as the bison parser generator, you may want to adjust the preprocessor's notion of the current file name and line number by hand. Parts of the output from bison are generated from scratch, other parts come from a standard parser file. The rest are copied verbatim from bison's input. You would like compiler error messages and symbolic debuggers to be able to refer to bison's input file.

bison or any such program can arrange this by writing #line directives into the output file. #line is a directive that specifies the original line number and source file name for subsequent input in the current preprocessor input file. #line has three variants:

#line linenum

linenum is a non-negative decimal integer constant. It specifies the line number which should be reported for the following line of input. Subsequent lines are counted from linenum.

#line linenum filename

linenum is the same as for the first form, and has the same effect. In addition, filename is a string constant. The following line and all subsequent lines are reported to come from the file it specifies, until something else happens to change that. filename is interpreted according to the normal rules for a string constant: backslash escapes are interpreted. This is different from #include.

Previous versions of CPP did not interpret escapes in #line; we have changed it because the standard requires they be interpreted, and most other compilers do.

#line anything else

anything else is checked for macro calls, which are expanded. The result should match one of the above two forms.

#line directives alter the results of the __FILE__ and __LINE__ predefined macros from that point on. Section 3.7.1 Standard Predefined Macros. They do not have any effect on #include's idea of the directory containing the current file. This is a change from GCC 2.95. Previously, a file reading

#line 1 "../src/gram.y"
#include "gram.h"

would search for gram.h in ../src, then the -I chain; the directory containing the physical source file would not be searched. In GCC 3.0 and later, the #include is not affected by the presence of a #line referring to a different directory.

We made this change because the old behavior caused problems when generated source files were transported between machines. For instance, it is common practice to ship generated parsers with a source release, so that people building the distribution do not need to have yacc or Bison installed. These files frequently have #line directives referring to the directory tree of the system where the distribution was created. If GCC tries to search for headers in those directories, the build is likely to fail.

The new behavior can cause failures too, if the generated file is not in the same directory as its source and it attempts to include a header which would be visible searching from the directory containing the source file. However, this problem is easily solved with an additional -I switch on the command line. The failures caused by the old semantics could sometimes be corrected only by editing the generated files, which is difficult and error-prone.

  Published under the terms of the GNU General Public License Design by Interspire