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.
Related
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.
I have been trying to compile netcat.c on AIX for some time (using the command make aix), but the compiler gives me some weird feedback such as :
"netcat.c", line 117.12: 1506-275 (S) Unexpected text 'int' encountered.
when checked the file netcat.c at line 117, I would find the line (second line in code below):
#ifdef HAVE_BIND
extern int h_errno;
/* stolen almost wholesale from bsd herror.c */
even if I changed the int into char for the same of testing, save the file and re-run the command I get the same error
am I missing something in reading the error code?
If you're using xlc (especially older ones), it's normally caused by declarations after statements, something like:
i = i + 1;
int x;
You probably need to give us a little more context, such as 10 or so lines before the error line.
My advice would be to get gcc running on that box if you are using an older xlc. IBM makes some fine compilers now but the earlier ones weren't so crash hot (in my opinion).
When innocent-looking code produces bizarre errors, try running the code through the C preprocessor stage, and looking at it then. Sometimes macros do very funny things.
Also note that a problem on an earlier line (missing semicolon, etc.) might produce an error message on a later line.
The post maybe already a little outdated, but just in case someone else comes along with the same problem ...
Here (AIX 7.1) h_errno is defined as macro in netdb.h.
/usr/include/netdb.h:#define h_errno (*(int *)h_errno_which())
Therefore the declaration in netcat.c line 117 does not work.
I just changed the line into
#ifndef h_errno
extern int h_errno;
#endif
and the compilation worked smoothly.
#A.Rashad, I moved the HAVE_BIND #ifdef block from line 117 to line 30 which is just under the #include "generic.h" declaration. This permitted the xlc to compile it. The (S)yntax error messages are gone and while there are some (W)arning messages, I do get an nc binary at the end!
hth,
Kevin
I am generating C code based on information provided by another file (an XML file). Certain chunks of C are included in this XML file and should be included verbatim in my generated C file. I wish to use the #line directive, so that if these chunks contain an error, the user will see the line number in the XML file that the chunk came from. For example, I wish to generate code like:
int main() {
#line 35 "file.xml"
....
#line
}
I wish to somehow "close" the #line section, I mean I think if there is an error e.g. with the closing } and that is generated by my program, the user should not see "error on line 36 of file.xml", that will be meaningless to them and confuse them.
For example, I could imagine a #line directive on its own (as in my example) would do something like that. But it doesn't work, and there is no such mention of any such facility in the gcc docs on #line.
Is there any such facility I'm missing? Or am I just asking for something that doesn't exist? How would you go about such a problem?
You need to issue another #line directive "resetting" to the line and filename of your original file.
When I try to precompile a *.pc file that contains a #warning directive I recieve the following error:
PCC-S-02014, Encountered the symbol "warning" when expecting one of the following: (bla bla bla).
Can I somehow convince Pro*C to ignore the thing if it doesn't know what to do with it? I can't remove the #warning directive as it's used in a header file that I can't change and must include.
According to the Pro*C/C++ Programmer's Guide (chapter 5 "Advanced Topics"), Pro*C silently ignores a number of preprocessor directives including #error and #pragma, but sadly not #warning. Since your warning directives are included in a header file, you might be able to use the ORA_PROC macro:
#ifndef ORA_PROC
#include <irrelevant.h>
#endif
For some reason, Pro*C errors out if you try to hide a straight #warning that way, however.
use option parse=none with proc
You can't. Pro*C only knows #if and #include. My best advice would be to preprocess the file as part of your build process to remove stuff Pro*C won't like. Something like
grep -v -E '^#(warning|pragma|define)' unchangeable.h >unchangeable.pc.h
My other advice would be to avoid the abomination which is Pro*C, but I'm guessing you're stuck with it...
Jons Ericsons answer is correct.
There is a second circumstance where you may need to use that trick.
Some versions of Pro*c can't deal with include files that don't have a file extension.
The ORA_PROC constant is one workable solution to that problem as well.
/bin/make -f /css/hwmig/pcprg/proc9i32.mk PROCFLAGS="sqlcheck=SEMANTICS userid=cssd/india09" PCCSRC=bic I_SYM=include= pc1
proc sqlcheck=SEMANTICS userid=cssd/india09 iname=bic include=. include=/oracle/Ora92/precomp/public include=/oracle/Ora92/rdbms/public include=/oracle/Ora92/rdbms/demo include=/oracle/Ora92/plsql/public include=/oracle/Ora92/network/public
Pro*C/C++: Release 9.2.0.6.0 - Production on Tue Dec 2 14:05:38 2008
Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.
System default option values taken from: /oracle/Ora92/precomp/admin/pcscfg.cfg
Syntax error at line 135, column 2, file /usr/include/standards.h:
Error at line 135, column 2 in file /usr/include/standards.h
warning The -qdfp option is required to process DFP code in headers.
.1
PCC-S-02014, Encountered the symbol "warning" when expecting one of the followin
g:
a numeric constant, newline, define, elif, else, endif,
error, if, ifdef, ifndef, include, line, pragma, undef,
an immediate preprocessor command, a C token,
The symbol "newline," was substituted for "warning" to continue.
Syntax error at line 30, column 7, file bic.pc:
Error at line 30, column 7 in file bic.pc
FILE fp;
......1
PCC-S-02201, Encountered the symbol "" when expecting one of the following:
; , = ( [
The symbol ";" was substituted for "*" to continue.
Error at line 0, column 0 in file bic.pc
PCC-F-02102, Fatal error while doing C preprocessing
Remove below two lines from /usr/include/standards.h
warning The -qdfp option is required to process DFP code in headers.
else
Modify /usr/include/standards.h.
Delete the line #warning The -qdfp option is required to process DFP code in headers. The proc does not support the #warning,just #else #if etc.