Understanding and parsing warnings from gcc - c++

When compiling a .cpp file from Emacs through M-x compile (which runs the folder's Makefile), I see the following on the compilation buffer (displayed in compilation mode):
In file included from: /path/to/file1:60,
from /path/to/file2.h:15,
from /path/to/file3.cpp:16:
/path/to/file4.h:28:2: #warning This file includes at least one deprecated or antiquated header which may be removed without
further notice at a future date. Please use a non-deprecated interface
with equivalent functionality instead. For a listing of replacement
headers and interfaces, consult the file backward_warning.h. To
disable this warning use -Wno-deprecated.
Aside from the actual warning message, how should I understand this trace? i.e. which file generated the warning? (file1,file2, file3 or file4)?
Also, why is there a comma after the file2 line, a colon after the file3 line, the line with file4 includes two numbers separated with two colons?
I am using Emacs 24.2.1, with gcc-4.4.5-x86_64.

The construct that actually triggered the warning (a #warning preprocessor directive, in this case) is in file4. The stuff above that is a trace of the #include stack, innermost-but-one first: in this case, file3 included file2, which included file1, which included file4.
When gcc knows the column number of the construct that triggered a diagnostic, it prints the file name, a colon, the line number, another colon, and the column number, as you see on the file4 line. The first number is the line number (28) and the second number is the column number (in this case, you will find that the # of #warning is in column 2). When gcc doesn't know the column number, it just prints the file name, a colon, and the line number. This is the case for the #include stack, as it does not bother recording the exact column of #include directives. Emacs' compilation-mode understands how to parse both these syntaxes: you will find that if you use C-x ` to page through the diagnostics, when there is a column number available, Emacs will place the cursor at the appropriate column.
The colons and commas at the ends of these reports are just to conform to English punctuation convention; they don't mean anything.

The warning was generated in file4.h, on line 28.
The comma is because you're in the middle of a list, the colon designates the end of the list. The two numbers are line number and column number.

Actually show its compilation path saying that:
in column 2 of line 28 of file4.h
that included from file1.h(line 60)
that included from file2.h(line 15)
that included from file3.cpp(line 16)
there was a warning ...
Every compiler should keep this track and it has nothing to do with GCC is smart or something!!
Since your compiler only compile file3.cpp and every other file will only parsed as a result of inclusion from this file.

Related

Checking an external file against set of functions and printing error alongwith line number using c++

I have a GEDCOM file, which I am supplying to my program, my program checks the content of GEDCOM file against a set of functions.
If the contents of file, fail to match the requirements of function, it should throw an error along with the line number on the GEDCOM file where error exists.
I would also like to mention that I have tried using macros like LINE, FILE but they are printing the contents of source code like line of source code and file name of source code.
Thanks in advance
If you are reading the file one line at a time you can keep a counter of the number of lines you have read from the file.
If you already have the whole file in one big buffer you can scan the number of newline or return characters.
If you provide a MCV example demonstrating your code reading in the file I can maybe help more.

How can I grep through all files #included in the file currently open in vim?

Suppose I have the following .hpp file open in vim:
#pragma once
#include "a.hpp"
#include "b.hpp"
#include "c.hpp"
#include <boost/something.hpp>
// some code
Now, let's say I want to search for any occurrence of the term Token in any of the included files (possibly in the files they include as well). How can I do this easily?
I would like to skip over any files not locatable from my current vimpath, e.g. in this case I might not have boost in my path so I would want it to simply not search in boost/something.hpp.
You can use the include-search functionality available in vim. In particular, this is the command required to search for all occurrences of Token when you have the cursor over that word:
[I Display all lines that contain the keyword under the
cursor. Filenames and line numbers are displayed
for the found lines. The search starts at the
beginning of the file. {not in Vi}
To jump to the first occurrence you can use:
[<Tab>
Taken from Bram's presentation Seven habits of effective editing at time 26'08".
This last command is also described in Vim's help as following:
[ CTRL-I Jump to the first line that contains the keyword
under the cursor. The search starts at the beginning
of the file. Lines that look like a comment are
ignored (see 'comments' option). If a count is given,
the count'th matching line is jumped to, and comment
lines are not ignored. {not in Vi}
See :help include-search for several methods to automatically search included files in Vim. For simple token searches, [i is probably the easiest solution. If you need a full regular expression, or if you don't have the token somewhere to put your cursor over it, you can use the :isearch command.

g++ -E option output

Using this option I receive files after preprocessing. There are many lines like:
# 91 "/usr/include/stdint.h" 3 4
What do the numbers mean? First I thought that #91 is the number of line where file is included, but that is not it. And about 3 4 I have no idea at all.
According to the official documentation, the line is of the format:
# linenum filename flags
The linenum specifies that the following line originated in filename at that line number. Then there are four flags:
1 - Start of a new file
2 - Returning to a file
3 - System header file
4 - Treat as being wrapped in extern "C"
So let's interpret your linemarker:
# 91 "/usr/include/stdint.h" 3 4
The following line originated from line 91 of /usr/include/stdint.h. It is a system header file and should be treated as wrapped in extern "C".
These are called "line markers". From the documentation:
Source file name and line number information is conveyed by lines of the form
# linenum filename flags
These are called linemarkers. They are inserted as needed into the output (but never within a string or character constant). They mean that the following line originated in file filename at line linenum. filename will never contain any non-printing characters; they are replaced with octal escape sequences.
After the file name comes zero or more flags, which are ‘1’, ‘2’, ‘3’, or ‘4’. If there are multiple flags, spaces separate them. Here is what the flags mean:
‘1’ -
This indicates the start of a new file.
‘2’ -
This indicates returning to a file (after having included another file).
‘3’ -
This indicates that the following text comes from a system header file, so certain warnings should be suppressed.
‘4’ -
This indicates that the following text should be treated as being wrapped in an implicit extern "C" block.
There are flags (space separated) and the meaning is:
1 - Start of a new file
2 - Returning to previous file
3 - Following text comes from a system header file (#include <> vs #include "")
4 - Following text should be treated as being wrapped in an implicit extern "C" block.

What does #line mean?

What does the following line do?
#line 25 "CSSGrammar.y"
And what's with the extension?
According to the Standard:
§16.4.3:
A preprocessing directive of the form
# line digit-sequence new-line
causes the implementation to behave as if the following sequence of source lines begins with a source line
that has a line number as specified by the digit sequence (interpreted as a decimal integer). If the digit
sequence specifies zero or a number greater than 2147483647, the behavior is undefined.
§16.4.4:
A preprocessing directive of the form
# line digit-sequence " s-char-sequenceopt" new-line
sets the presumed line number similarly and changes the presumed name of the source file to be the contents
of the character string literal.
§16.4.5:
A preprocessing directive of the form
# line pp-tokens new-line
(that does not match one of the two previous forms) is permitted. The preprocessing tokens after line
on the directive are processed just as in normal text (each identifier currently defined as a macro name is
replaced by its replacement list of preprocessing tokens). If the directive resulting after all replacements
does not match one of the two previous forms, the behavior is undefined; otherwise, the result is processed
as appropriate.
The .y extension is just what the author chose to use, perhaps to make it apparent that it was a YACC file (the word "grammar" also points to that though it's just a guess).
It simply states that the current line of code is sourced from line 25 of CSSGrammar.y, a YACC-style grammar file which is where this code was generated.
This can be used by debuggers to step into the grammar itself as opposed to the generated code.
#line directive modifies the reporting position for the compiler, and is used by code generating software to help the programmer identify the issue in the original source. It can be used by anyone to help redirect error reporting to be more informative.
So for instance your parser generates a CSSGrammar.cpp file say, which is compiled by the c++ compiler, and has c++ snippets in it, a #line 25 "CSSGrammar.y" directive tells the c++ compiler to treat that particular point in the file as if it is line number 25 from CSSGrammar.y
The compiler will continue to parse subsequent lines and report errors under the initial conditions of that directive.
So if an error occurs 3 lines later it would report that an error occurred on line 28 in CSSGrammar.y
Note that a single source file can have sources coming in from multiple parts; and that this directive can be used quite effectively to indicate error conditions.
Typically you'll see that there are multiple #line directives along the way; they are just there to account for various injections along the way (to reset the reporting caret if you will).
Note that #line directive can be used by ANY generator including your own, and is not limited to in anyway parser generators.
It a directive for the compiler to believe that the following line is the line number 25 in file CSSGrammar.y. Then, if an error is detected by the compiler on the 2nd next line, it would be reported as coming from line 26 of CSSGrammar.y
Programs generating C files, like bison, or yacc, or flex, or ANTLR, or even the (obsolete) MELT use that possibility a lot.
If debugging information is generated (e.g. with gcc -g), it will point to the CSSGrammar.y file in your example.
The 'yacc' parser generator consumes files that end in .y, and emits files that contain c or c++. It adds these #line lines to allow a debugger to get back to ye olde original source, accept no substitutes.
it's a c preprocessor option. It tells the c-parser to drop it's line count of the source file an pretend, that this is line #25.
With this information it's easier for you to debug the the source file. The yacc file will be translated into a c-source, where this is the pretended source line.
Using #line forces the compiler to experience amnesia about what file it's compiling and what line it's on, and loads in the new data.
Note: The compiler still compiles from the line it was on.

Hints and tools for finding unmatched braces / preprocessor directives

This is one of my most dreaded C/C++ compiler errors:
file.cpp(3124) : fatal error C1004: unexpected end-of-file found
file.cpp includes almost a hundred header files, which in turn include other header files. It's over 3000 lines. The code should be modularized and structured, the source files smaller. We should refactor it. As a programmer there's always a wish list for improving things.
But right now, the code is a mess and the deadline is around the corner. Somewhere among all these lines—quite possibly in one of the included header files, not in the source file itself—there's apparently an unmatched brace, unmatched #ifdef or similar.
The problem is that when something is missing, the compiler can't really tell me where it is missing. It just knows that when it reached end of the file it wasn't in the right parser state.
Can you offer some tools or other hints / methodologies to help me find the cause for the error?
If the #includes are all in one place in the source file, you could try putting a stray closing brace in between the #includes. If you get an 'unmatched closing brace' error when you compile, you know it all balances up to that point. It's a slow method, but it might help you pinpoint the problem.
One approach: if you have Notepad++, open all of the files (no problem opening 100 files), search for { and } (Search -> Find -> Find in All Open Documents), note the difference in count (should be 1). Randomly close 10 files and see if the difference in count is still 1, if so continue, else the problem is in one of those files. Repeat.
Handy tip:
For each header file, auto-generate a source file which includes it, then optionally contains an empty main method, and does nothing else. Compile all of these files as test cases, although there's no point running them.
Provided that each header includes its own dependencies (which is a big "provided"), this should give you a better idea which header is causing the problem.
This tip is adapted from Google's published C++ style guide, which says that each component's source files should include the interface header for that component before any other header. This has the same effect, of ensuring that there is at least one source file which will fail to compile, and implicate that header, if there's anything wrong with it.
Of course it won't catch unmatched braces in macros, so if you use much in the way of macros, you may have to resort to running the preprocessor over your source file, and examining the result by hand and IDE.
Another handy tip, which is too late now:
Check in more often (on a private branch to keep unfinished code out of everyone else's way). That way, when things get nasty you can diff against the last thing that compiled, and focus on the changed lines.
Hints:
make small changes and recompile after each small change
for unmatched braces, use an editor/IDE that supports brace match hilighting
if all else failds, Ye Olde method of commenting out blocks of code using a binary chop approach works for me
Very late to the party, but on linux you can use fgrep -o
-o, --only-matching
Print only the matched (non-empty) parts of a matching line,
with each such part on a separate output line.
So if you fgrep -o { then you'll get a list of all the opening braces in your file.
You can then pipe that to wc -l and that will give you the number of opening braces in your file.
With a bit of bash arithmetic, you can do the same with closing braces, and then print the difference.
In the below example I'm using git status -s to get the short-format output of all modified files from my git repo, and then I'm iterating over them to find which files may have mismatched braces
for i in $(git status -s | awk '{print $2}'); do
open=$(fgrep -o { $i | wc -l); # count number of opening braces
close=$(fgrep -o } $i | wc -l); # count number of closing braces
diff=$((open-close)); # find difference
echo "$diff : $i"; # print difference for filename
done
I think using some editor with brace highlighting will help. There should also be some tools around that do automatic indention on code.
EDIT: Does this vim script help? It seems to do #ifdef highlighting.
Can you create a script that actually does all the including, and then write the whole stuff to a temporary file? Or try the compiler for helping you with that? Then you can use the bracket highlighting features of various editors to find the problem and you'll probably be able to identify the file. (An extra help can be to have your script add a comment around every included file).
This might not be relevant to your problem, but I was getting an "Unexpected #else" error when framing some header files in an #if/#else/#endif block.
I found that if I set the problem modules to not use pre-compiled headers, the problem went away. Something to do with the "#pragma hdrstop" should not be within an #if/#endif.
Have a look at this question (Highlighting unmatched brackets in vim)
Pre-compile your code first, this will create a big chunk with the include files stuffed into the same file. Then you can use those brace-matching scripts.
I recently ran into this situation while refactoring some code and I'm not a fan of any of the answers above. The problem is that they neglect to incorporate a pretty basic assumption:
Any given file (most likely) will have matching braces and if/endif macros.
While it is true one can have a C++ source file that opens a bracket or an if block and includes another module that closes it, I have never seen this in practice. Something like the following:
foo.cpp
namespace Blah{
#include "bar.h"
bar.h:
}; /// namespace Blah
So with the assumption that any given file / module contains matching sets of braces and preprocessor directives, this problem is now trivial to solve. We just need a script to read the files / count the brackets & directives that it finds and report mismatches.
I've implemented one in Ruby here, feel free to take and adapt to your needs:
https://gist.github.com/movitto/6c6d187f7a350c2d71480834892552ab
I just spent an hour with a problem like this. It was very hard to spot, but in the end, I had typed a double # on one line:
##ifdef FEATURE_X
...
That broke the world.
Easy one to search for though.
The simplest and fastest solution is to comment file from the end by consistent blocks. If the error still exists, then you not yet comment the open brace.