What's the meaning of #line in the C language? Where would it be used?
It tells the compiler where the following line actually came from. It's usually only the C preprocessor that adds these, for example, when including a file, it tells the compiler (which is basically only seeing one stream of data) that we're looking at a different file.
This may sound strange, but the preprocessor simply inserts the header files where you specify your includes, and the compiler works on the whole thing (all header files concatenated along with your source code), you can check the result of the preprocessor stage if using gcc with gcc -E myfile.c. In there you'll notice it adds a #line directive whenever you include files, and also whenever it reduces the amount of text fed to the compiler (such as large amounts of comments may be reduced to a single #line directive, skipping ahead)
It is also used by other programs, such as bison/yacc to tell you that the problem (if there's a compile problem) is related to your rules-file at a specific line, which the compiler would otherwise be unable to do, as the bison/yacc generates c-files.
It is called the preprocessor line control directive.
The expansions of both __FILE__ and __LINE__ are altered if a #line directive is used.
It causes the compiler to view the line number of the next source line as the specified number.
Its main use is to make the compiler provide more meaningful error messages.
You can find more explanation and a usage example in IBM's documentation.
It is a pragma keyword:
"#line lets you modify the compiler's line number and (optionally) the file name output for errors and warnings. This example shows how to report two warnings associated with line numbers. The #line 200 directive forces the line number to be 200 (although the default is #7) and until the next #line directive, the filename will be reported as "Special". The #line default directive returns the line numbering to its default numbering, which counts the lines that were renumbered by the previous directive."
It allows you to change the apparent line number of the file.
The only use I can think of for it is to make the line numbers sane after a long series of multi-line macros.
usage is:
#line 42
It is mostly used to supply the file names and line numbers of a source file from which a C file (be it header or implementation) was created. Given that, the compiler would emit diagnostics that hint at the source file rather than at the generated file.
Preprocessors also use this to hint at included headers in a preprocessed file that has these expanded.
# is the string injing symbol to the processor c and c++
Related
I am looking through some proprietary source code: sample programs in using a library.
The code is written in C and C++, using make for build system.
Each and every file ends in a commented out []: /*[]*/ for source files and #[]# for makefiles. What could be the reason for this?
The code is compiled for ARM with GCC, using extensions.
It is most likely a place holder for some sort of automatic expansion.
Typically something like macrodef (or one of the source code control filters) would expand such items to contain some relevant text. As typically only the comment-protected brackets would expand, the comments would remain in place, protecting the source code from actual expanded items at compilation time.
However, what you are currently looking at is probably the outer containing brackets with all of the internal expansions removed. This may have been done during a code migration from one source code control system to another. Although such an idea is highly speculative, it does not appear that they took the effort to migrate expansion items, instead of just removing them.
On one project I used to work, every C source file contained a comment at the very end:
/* End of file */
The reason for that was the gcc warning
Warning : No new line at end of file
So we had this comment (with a new line after it) to be sure people do not write after the comment :)
Is it possible to get the list of #defines(both compile time and defined in the source code) used in a C program while execution.
Because i am having a project having lot of C source files.
Is there any compile time option to get that?
GNU cpp takes various -d options to output macro and define data. See their man pages for more details.
for gcc, you can use one of the following:
-dCHARS CHARS is a sequence of one or more of the following characters, and must not be preceded by a space. Other characters are interpreted by the compiler proper, or reserved for future versions of GCC, and so are silently ignored. If you specify characters whose behavior conflicts, the result is undefined.
M'
Instead of the normal output, generate a list of#define' directives for all the macros defined during the execution of the preprocessor, including predefined macros. This gives you a way of finding out what is predefined in your version of the preprocessor. Assuming you have no file foo.h, the command
touch foo.h; cpp -dM foo.h
will show all the predefined macros.
If you use -dM without the -E option, -dM is interpreted as a synonym for -fdump-rtl-mach. See Debugging Options.
D'
LikeM' except in two respects: it does not include the predefined macros, and it outputs both the #define' directives and the result of preprocessing. Both kinds of output go to the standard output file.
N'
Like `D', but emit only the macro names, not their expansions.
I'
Output#include' directives in addition to the result of preprocessing.
U'
LikeD' except that only macros that are expanded, or whose definedness is tested in preprocessor directives, are output; the output is delayed until the use or test of the macro; and `#undef' directives are also output for macros tested but undefined at the time.
In gcc the command you probably want is
gcc -dM -E [your_source_files]
I know this is implicitly in the above answers, but perhaps someone needs (like myself) the quick recipe.
I unfortunately was doing a little code archeology today (while refactoring out some old dangerous code) and found a little fossil like this:
# line 7 "foo.y"
I was completely flabbergasted to find such an archaic treasure in there. I read up on it on a website for C programming. However it didn't explain WHY anyone would want to use it. I was left to myself therefore to surmise that the programmer put it in purely for the sheer joy of lying to the compiler.
Note:
(Mind you the fossil was actually on line 3 of the cpp file) (Oh, and the file was indeed pointing to a .y file that was almost identical to this file.
Does anyone have any idea why such a directive would be needed? Or what it could be used for?
It's generally used by automated code generation tools (like yacc or bison) to set the line number to the value of the line in the actual source file rather than the C source file.
That way, when you get an error that says:
a += xyz;
^ No such identifier 'xyz' on line 15 of foo.y
you can look at line 15 of the actual source file to see the problem.
Otherwise, it says something ridiculous like No such identifier 'xyz' on line 1723 of foo.c and you have to manually correlate that line in your auto-generated C file with the equivalent in your real file. Trust me, unless you want to get deeply involved in the internals of lexical and semantic analysis (or you want a brain haemorrhage), you don't want to go through the code generated by yacc (bison may generate nicer code, I don't know but nor do I really care since I write the higher level code).
It has two forms as per the C99 standard:
#line 12345
#line 12345 "foo.y"
The first sets just the reported line number, the second changes the reported filename as well, so you can get an error in line 27 of foo.y instead of foo.c.
As to "the programmer put it in purely for the sheer joy of lying to the compiler", no. We may be bent and twisted but we're not usually malevolent :-) That line was put there by yacc or bison itself to do you a favour.
The only place I've seen this functionality as being useful is for generated code. If you're using a tool that generates the C file from source defined in another form, in a separate file (ie: the ".y" file), using #line can help the user know where the "real" problem is, and where they should go to correct it (the .y file where they put the original code).
The purpose of the #line directive is mainly for use by tools - code generators can use it so that debuggers (for example) can keep context of where things are in the user's code or so error messages can refer the user to the location in his source file.
I've never seen that directive used by a programmer manually putting it in - and I;m not sure how useful that would be.
It has a deeper purpose. The original C preprocessor was a separate program from the compiler. After it had merged several .h files into the .c file, people still wanted to know that the error message is coming from line 42 of stdio.h or line 17 of main.c. Without some means of communication, the compiler would otherwise have no way to know which source file originally held the offending line of code.
It also influences the tables needed by any source-level debugger to translate between generated code and source file and line number.
Of course, in this case, you are looking at a file that was written by a tool (probably named yacc or bison) that is used to create parsers from a description of their grammar. This file is not really a source file. It was created from the real source text.
If your archaeology is leading you to an issue with the parser, then you will want to identify what parser generator is actually being used, and do a little background reading on parsers in general so you understand why it doing things this way at all. The documentation for yacc, bison, or whatever the tool is will likely also be helpful.
I've used #line and #error to create a temporary *.c file that you compile and let your IDE give you a browsable list of errors found by some 3rd party tool.
For example, I piped the output file from PC-LINT into a perl script which converted the human readable errors to #line and #error lines. Then compiled this output, and my IDE lets me step through each error using F4. A lot faster that manually opening up each file and jumping to a particular line.
Say I have a constant:
#define PI 3.14
Say I have a static library with multiple header and source files. If I declare this in the header file, will its scope apply to all of the source files? Or do the source files need to include the header with the declaration of PI?
They will need to include the file which contains #define PI 3.14, otherwise the preprocessor will not read the #define line, and subsequently the compile will fail.
In C++, a good way to think of the compile process is that each individual C++ file is first run through a preprocessor, which takes all the #define, #include, and other preprocessor statements and replaces them throughout the code, then compiled (at this point, the C++ file and anything brought in via #include treated almost as if they were one very large single file), then after that, a linker takes the final output of the preprocess/compile stage for all of the C++ files and assembles them into one final output file. The preprocessor (Which handles the defines) works before the compile stage, not during linkage.
The definition has to be included in each module.
Technically, it has no "scope". It is only a text replacement operation that happens prior to compilation. You could also look into your compiler settings for a way to specify pre-processor definitions. This is often a project setting available easily through your IDE.
They will need to include the define, however if you need a define across all files you can do a compiler level switch.
Is there a way to make the GNU C Preprocessor, cpp (or some other tool) list all available macros and their values at a given point in a C file?
I'm looking for system-specific macros while porting a program that's already unix savvy and loading a sparse bunch of unix system files.
Just wondering if there's an easier way than going hunting for definitions.
I don't know about a certain spot in a file, but using:
$ touch emptyfile
$ cpp -dM emptyfile
Dumps all the default ones. Doing the same for a C file with some #include and #define lines in it includes all those as well. I guess you could truncate your file to the spot you care about and then do the same?
From the man page:
-dCHARS
CHARS is a sequence of one or more of the following characters, and must not be preceded by a space. Other characters are interpreted by the compiler proper, or reserved for future versions of GCC, and so are silently ignored. If you specify characters whose behavior conflicts, the result is undefined.
M
Instead of the normal output, generate a list of #define directives for all the macros defined during the execution of the preprocessor, including predefined macros. This gives you a way of finding out what is predefined in your version of the preprocessor. Assuming you have no file foo.h, the command
touch foo.h; cpp -dM foo.h
will show all the predefined macros.
If you use -dM without the -E option, -dM is interpreted as a synonym for -fdump-rtl-mach.
D
Like M except in two respects: it does not include the predefined macros, and it outputs both the #define directives and the result of preprocessing. Both kinds of output go to the standard output file.
N
Like D, but emit only the macro names, not their expansions.
I
Output #include directives in addition to the result of preprocessing.
With gcc, you can use the "-dD" option to dump all the macro definitions to stdout.
Why not consult the section on Predefined-macros? Do you need this for building a project or some such thing?
To list "their values at a given point in a C file" using macros, there is two that can demonstrate a given point in a C file, especially when compiled, and would be deemed useful for tracing a point of failure...consider this sample code in a file called foo.c:
if (!(ptr = malloc(20))){
fprintf(stderr, "Whoops! Malloc Failed in %s at line %d\n", __FILE__, __LINE__);
}
If that code logic was used several times in this file, and the call to malloc was failing, you would get this output:
Whoops! Malloc Failed in foo.c at line 25
The line number would be different depending on where in the source, that logic is used. This sample serves the purpose in showing where that macro could be used...
Here is a link to a page with an overview of command-line options to list predefined macros for most compilers (gcc, clang...).