Here is the problem:
I have a C source file main.c and the corresponding preprocessed file main.i. Given a line in main.i, how can I get the corresponding line number in main.c?
The C standard does not specify this. GCC and Clang emit lines starting with # followed by a space, a line number, a file name, and other information.. You can determine the line number in main.c:
Read the preprocessed file, main.i. After any line with # followed by a space, a number, and a file name that is not “main.c”, read and ignore further lines until there is a # followed by a space, a number, and “main.c”. Remember that number as the current line number.
Subsequent lines until another # line in this form are lines from main.c (after preprocessing) with consecutive line numbers continuing from the line number remembered above.
When used as a separate phase to produce a text file, the C preprocessor usually inserts #line directives, sometimes appearing as bare # directives providing the original line number, file name and other contextual information. #line directives have this form:
# line pp-tokens new-line
which after macro substitution should become:
# line digit-sequence new-line
or
# line digit-sequence " s-char-sequenceopt " new-line
Where digit-sequence is the line number of the next list in the source stream and the s-char-sequenceopt is the name of the file to use for diagnostics and as a replacement for the __FILE__ macro. Subsequent newlines increment the line number thus defined.
#line directives are produced by external programs that generate C code files to make compiler diagnostics point to the original source file.
C Compilers such as gcc and clang produce similar information in their preprocessing output in the form:
# number filename other-information new-line
This syntax is not defined by the C Standard but very common in preprocessing output produced by C compilers. The C standard does not define this output, used mostly for debugging purposes.
Related
I tried to use the #error directive with GCC compiler like this:
#error "The charging pins aren't differing! One pin cannot be used for multiple purposes!"
This says, I should use double quotes, so the argument will be a single string constant and I can use an apostrophe inside of it. However, I want this string to be appeared in the source code in mutiple lines, like:
#error "The charging pins aren't differing!
One pin cannot be used for multiple purposes!"
Then, I got some error messages:
warning: missing terminating " character
#error "The charging pins aren't differing! One pin
error: missing terminating " character
cannot be used for multiple purposes!"
If I insert a blackslash at the end of the first line, the diagnostic message conatains all the whitespaceb between the beginning of the second line and the first word (One). If both lines are strings the diagnostic message shows the inner double quotes.
So the question: How can I achieve this output? (or a similar wihtout double quotes, but the apostrophe included)
#error "The charging pins aren't differing! One pin cannot be used for multiple purposes!"
Unfortunately, you can't have it all.
Either you have to get rid of the apostrophe so that the message only contains what's regarded as valid pre-processing tokens.
Or you can write it as a string on a single line.
Or you can write it two string literals and break the line with \. You can't do this in the middle of a string literal, because then it wouldn't be a valid pre-processing token. This will make the output look weird though, like : error: "hello" "world".
Relying on pre-processor concatenation of two string literals won't work, since the error directive only looks until it spots a newline character in the source. And the error directive translates everything you type into strings anyway.
The relevant translation phases are (from C17 5.1.1.2) executed in this order:
2) Each instance of a backslash character () immediately followed by a new-line
character is deleted, splicing physical source lines to form logical source lines.
3) The source file is decomposed into preprocessing tokens and sequences of
white-space characters (including comments).
4) Preprocessing directives are executed, ...
6) Adjacent string literal tokens are concatenated.
#error is executed in step 4, earlier than string literal concatenation in step 6.
I personally think the best solution is to skip the apostrophe:
#error The charging pins are not differing! \
One pin cannot be used for multiple purposes!
Slight fix of English and you get the best compromise between readable source and a readable error message.
As stated here
Neither ‘#error’ nor ‘#warning’ macro-expands its argument.
Internal whitespace sequences are each replaced with a single space. The line must consist of complete tokens. It is wisest to make the argument of these directives be a single string constant; this
avoids problems with apostrophes and the like.
So you can use it in single line only.
#include <stdio.h>
//#define var 10
#ifdef var
#error "The charging pins aren't differing! One pin cannot be used for multiple purposes!"
#endif
int main(void){
printf("in main() \n");
return 0;
}
Use double-quotes and \ to split the string on multiple lines:
#error "These aren't \
working!"
MSVC (v19.14) outputs:
<source>(2): fatal error C1189: #error: "These aren't working!"
GCC (v5.5) outputs:
<source>:1:2: error: #error "These aren't working!"
#error "These aren't \
^
I was inspecting the preprocessed output generated by GCC, and I see a lot of these in the .i file that I generated using the -save-temps flag:
# 8 "/usr/include/i386-linux-gnu/gnu/stubs.h" 2 3 4
What do the numbers before and after the absolute path of stubs.h mean? It seems to be some kind of debugging information that is inserted by the preprocessor and allows the compiler to issue error messages referring to this information. These lines do not affect the program itself, but what specifically is each number for?
Based on the documentation the number before the filename is the line number. The numbers after the file name are a flag and mean the following:
1 indicates the start of a new file.
2 indicates returning to a file (after having included another file).
3 indicates that the following text comes from a system header file, so certain warnings should be suppressed.
4 indicates that the following text should be treated as being wrapped in an implicit extern "C" block.
I've just encountered a C file which contains both preprocessor directives and lines that look like this:
# 9 "filename"
I have never seen such lines before. What do they mean? I'm guessing these are preprocessor directives, but what does the preprocessor do with them?
Also, for some of the lines the string doesn't even represent an existing filename...
I believe it's another way of using the #line preprocessor directive.
For example you could write:
// you could write #line 7 "filename" or
// # 7 "filename" or
// # 7 or
#line 7
int main(void)
{
printf("%d\n", __LINE__);
And all of them would give you (in this case) 10 on stdout.
And a note about the "filename" part it's optional and unverified (that's why it can be anything, even a file that doesn't exist). Its use is explained in the link I provided -
If you specify a file name, the compiler views the next line as part of the specified file. If you do not specify a file name, the compiler views the next line as part of the current source file.
Am using visual cl.exe compiler to get an intermediate file after preprocessing.
all the #define are removed. is there any possibility to keep them in the intermediate file?
No. One of the tasks of the preprocessing is to remove all #define and others preprocessing stuffs the #s and creates a plain c file.
What you can do:
use the /E or /P to output the preprocess to the output or file: http://blog.kowalczyk.info/article/clexe-cmd-line-args.html
#define is a preprocessor instruction so obviously it won't be present in a preprocessed source file. Every occurrence of a preprocessor constant will be replaced with its actual value by the preprocessor.
I am trying to understand some code and I've come across a keyword that I've never seen before. I tried to google it, but haven't found anything regarding it as well.
char *valtext;
#line 1 "Values.l"
#define INITIAL 0
#line 2 "Values.l"
int reserve(char *s);
#line 388 "lex.val.c"
I've included the entire block hoping that perhaps someone can help me understand this chunk of code. I can't find any files on my system named "Values.l" and this chunk of code is located in the "lex.val.c" file.
Thanks in advance.
A #line directive sets the compiler's setting for the current file name and line number. This affects the __FILE__ and __LINE__ symbols, the output generated by a failing assert(), and diagnostic messages (errors and warnings). It's typically used by the preprocessor so that error and warning messages can refer to the original source code, not to the output of the preprocessor (which is typically discarded by the time you see any messages).
It's also used by other tools that generate C source code, such as lex/flex and yacc/bison, so that error messages can refer to the input file rather than the (temporary) generated C code.
The definitive reference is the C standard (pdf), section 6.10.4.
A line of the form
#line number
sets the current line number. A line of the form
#line number "file-name"
sets both the line number and the file name. You can also generate one of these two forms via macro expansion; for example:
#define LINE 42
#define FILE "foo.c"
#line LINE FILE
The #line directive is for the use of preprocessors, so that the original line number of the source can be communicated to the C compiler. It makes it so that error messages from the compiler properly refer to line numbers the user will understand.
For example, line 12 of your mycode.c may go through a preprocessor, and now be line 183 of mycode.tmp.cc. If the C compiler finds an error on that line, you don't want to be told the error is on line 183 of mycode.tmp.cc. So the C compiler needs to be given "original coordinates" of each line. The #line directive does this, telling the compiler the current line number and filename to use in error messages.
The line directive:
http://msdn.microsoft.com/en-US/library/b5w2czay%28v=VS.80%29.aspx
That code has gone through the pre-processor and as such is marked up by one stage of a compiler, intended to be consumed by another stage of the same compiler. The features that it uses aren't intended for your use.
The files that it references may be temporary files created by the compiler as it runs.
This is done so that the line number changes.
This is done in order to show the line numbers of the Lex input file, for example, in error messages and warnings. Because Lex generates C code, without #line directives compile errors and warnings wouldn't be of any value.