According to the C language standard, the lines between #if 0 and #endif are required only to contain preprocessing tokens, so most kinds of completely malformed syntax e.g. #foo or #include [bar] are allowed (silently ignored); GCC and Microsoft C++ do indeed silently ignore such.
An # does not as far as I can see correspond to any preprocessing token so should still be a syntax error. GCC and Microsoft C++ silently ignore it. Is this effectively a language extension or am I missing something?
Does anyone actually use the ability to put malformed syntax between #if 0 and #endif in practice?
Both the C and C++ standard contain a special 'escape clause' in their grammar that makes that every non-white-space character is (part of) a preprocessing token. For this reason, whatever you put in a block between #if 0 and #endif can almost never cause a compilation error. The only exception are mismatched quotes for character and string literals.
And yes, I regularly put malformed syntax between #if 0 and #endif to disable some partially-written code.
The preprocessor is what is sounds like: It processes files before (pre) the compiler. The input the actual compiler sees is what the preprocessor feeds it, and if a part of the code is between #if 0 and a matching #endif, then the compiler won't even see that code. That is why you can put almost anything in that section, the compiler will simply not see it.
Code between #if 0 and #endif is not going to include in final source code (after per-processor output). If you are using Visual Studio and want to see pre-processor's output,
Go to project property -> Select C/C++ -> Select Preprocessor -> Select 'Yes' in Preprocess to a file option.
Go to your project directory and you will see '.i' file. This is your preprocessor's output.
And you can see code between #if 0 and #endif is not included. So no question of error.
Related
I am trying to build freetype2 using my own build system (I do not want to use Jam, and I am prepared to put the time into figuring it out). I found something odd in the headers. Freetype defines macros like this:
#define FT_CID_H <freetype/ftcid.h>
and then uses them later like this:
#include FT_CID_H
I didn't think that this was possible, and indeed Clang 3.9.1 complains:
error: expected "FILENAME" or <FILENAME>
#include FT_CID_H
What is the rationale behind these macros?
Is this valid C/C++?
How can I convince Clang to parse these headers?
This is related to How to use a macro in an #include directive? but different because the question here is about compiling freetype, not writing new code.
I will address your three questions out of order.
Question 2
Is this valid C/C++?
Yes, this is indeed valid. Macro expansion can be used to produce the final version of a #include directive. Quoting C++14 (N4140) [cpp.include] 16.2/4:
A preprocessing directive of the form
# include pp-tokens new-line
(that does not match one of the two previous forms) is permitted. The preprocessing tokens after include
in the directive are processed just as in normal text (i.e., 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.
The "previous forms" mentioned are #include "..." and #include <...>. So yes, it is legal to use a macro which expands to the header/file to include.
Question 1
What is the rationale behind these macros?
I have no idea, as I've never used the freetype2 library. That would be a question best answered by its support channels or community.
Question 3
How can I convince Clang to parse these headers?
Since this is legal C++, you shouldn't have to do anything. Indeed, user #Fanael has demonstrated that Clang is capable of parsing such code. There must be some problem other problem in your setup or something else you haven't shown.
Is this valid C/C++?
The usage is valid C, provided that the macro definition is in scope at the point where the #include directive appears. Specifically, paragraph 6.10.2/4 of C11 says
A preprocessing directive of the form
# include pp-tokens new-line
(that does not match one of the two previous forms) is permitted. The
preprocessing tokens after include in 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.) The
directive resulting after all replacements shall match one of the two
previous forms.
(Emphasis added.) Inasmuch as the preprocessor has the same semantics in C++ as in C, to the best of my knowledge, the usage is also valid in C++.
What is the rationale behind these macros?
I presume it is intended to provide for indirection of the header name or location (by providing alternative definitions of the macro).
How can I convince Clang to parse these headers?
Provided, again, that the macro definition is in scope at the point where the #include directive appears, you shouldn't have to do anything. If indeed it is, then Clang is buggy in this regard. In that case, after filing a bug report (if this issue is not already known), you probably need to expand the troublesome macro references manually.
But before you do that, be sure that the macro definitions really are in scope. In particular, they may be guarded by conditional compilation directives -- in that case, the best course of action would probably be to provide whatever macro definition is needed (via the compiler command line) to satisfy the condition. If you are expected to do this manually, then surely the build documentation discusses it. Read the build instructions.
I have been looking at the Boost libraries source code, and I have noticed that often there are single pound signs without any preprocessor directives attached to them. I read through the GCC preprocessor manual and specification guide and can't find anything about it.
(1) #ifndef BOOST_CONFIG_HPP
(2) # include <boost/config.hpp>
(3) #endif
(4) #
(5) #if defined(BOOST_HAS_PRAGMA_ONCE)
(6) # pragma once
(7) #endif
On line 4, there is nothing after the pound sign. What effect does this have? Is it defined in the C preprocessor (CPP) specification?
As Boost is a cross-platform library, I would assume that any CPP should parse it correctly. What would the effect/side-effects be of having random pound/hash signs throughout the code?
A # on its own on a line has no effect at all. I assume it's being used for aesthetic value.
The C standard says:
6.10.7 Null directive
Semantics
A preprocessing directive of the form
# new-line
has no effect.
The C++ standard says the same thing:
16.7 Null directive [cpp.null]
A preprocessing directive of the form
# new-line
has no effect.
It makes the source code look pretty, that's all.
Highlights the fact that the whole block is a preprocessor section.
And indeed, both the C and C++ preprocessors must ignore # on a line.
Always check an authoritative source instead of relying on other resources. C is standardised as ISO 9899::2011, C++ also has an ISO standard. Both are well accepted and the final drafts available by a short search. The C standard states in 6.10.7 (C++ has much the same text):
A preprocessing directive of the form
# new-line
has no effect.
This is a null directive, as much as an ; without a preceeding expression in the core-language is a null statement .
For the preprocessor it is just for formatting/readability to highlight that the lines belong semantically together. (the semicolon OTOH is semantically relevant).
I'm trying to set a breakpoint in my objective c++ ( I think its called) code.
I've used #ifdef _cplusplus and #endif to wrap the code, but when I go to set a breakpoint in it, it breaks on the end of the method body, and none of the code in the body is run.
I've simplified the code I had, but I expect at least to see numbers being printed in the console because of the cout.
The file has the extension .mm too. I'm new to mixing C++ and Objective-C. Anything I've missed?
#ifdef is a preprocessor directive - in short, this means that without _cplusplus being #defined somewhere, your debugger is smart enough to say Hey, this is dead code - don't even try to debug it.
Preprocessor directives are lines included in the code of programs
preceded by a hash sign (#). These lines are not program statements
but directives for the preprocessor. The preprocessor examines the
code before actual compilation of code begins and resolves all these
directives before any code is actually generated by regular
statements.
These preprocessor directives extend only across a single line of
code. As soon as a newline character is found, the preprocessor
directive is ends. No semicolon (;) is expected at the end of a
preprocessor directive. The only way a preprocessor directive can
extend through more than one line is by preceding the newline
character at the end of the line by a backslash ().
These are super useful, and for a common example have a quick look at Include Guards. As a test to see what I mean, try adding #define _cplusplus directly above the #ifdef and try again.
I came across the following code in a .cpp file. I do not understand the construct or syntax which involves the header files. I do recognize that these particular header files relate to Android NDK. But, I think the question is a general question about C++ syntax.
These appear to be preprocessor commands in some way because they begin with "#". But, they are not the typical #include, #pragma, #ifndef, #define, etc. commands. The source file has more 1000+ such occurrences referencing hundreds of different .h, .c, .cpp files.
typedef int __time_t;
typedef int __timer_t;
# 116 "/home/usr/download/android-ndk-r8b/platforms/android-3/arch-arm/usr/include/machine/_types.h"
# 41 "/home/usr/download/android-ndk-r8b/platforms/android-3/arch-arm/usr/include/sys/_types.h" 2
# 33 "/home/usr/download/android-ndk-r8b/platforms/android-3/arch-arm/usr/include/stdint.h" 2
# 48 "/home/usr/download/android-ndk-r8b/platforms/android-3/arch-arm/usr/include/stdint.h"
typedef __int8_t int8_t;
typedef __uint8_t uint8_t;
The compiler (GCC) does not appear to be throwing any error related to these lines. But, I would like to understand their purpose and function. Can anybody explain these?
This is output from the GCC preprocessor. Those lines are known as linemarkers. They have the syntax:
# linenum filename flags
They are interpreted as saying that the following line has come from the line linenum from filename. They basically just help you and the compiler see where lines were included from. The flags provide some more information:
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.
You can see this output from preprocessing your own programs if you give the -E flag to g++.
You'll typically see lines like that in the output of the preprocessor (i.e., you normally shouldn't be seeing them at all).
They're similar to the standard #line directive, which has the form:
#line 42
or
#line 42 "foo.c"
which the compiler uses to control the contents of error messages.
Without the word line, this:
# 42 "foo.c"
is technically a non-directive (which, just to add to the fun, is a kind of directive). It's essentially a comment as far as the C standard is concerned. At a guess, gcc's preprocessor probably emits these rather than #line directives because #line directives are intended as input to the preprocessor.
gcc's preprocessor refers to these as "linemarkers"; they're discussed in the cpp manual. They're treated like #line directives, except that they can take an additional flag argument.
The preprocessors tend to introduce these directives and use them to indicate the line and filename. The C++ doesn't define the meaning but it reserves the use of
# <non-directive>
where is something which isn't one of the normal directives. It seems compiler writes have agreed to use the line number and filename in these as the result of preprocessing the file. This use is similar to basically all compilers supporting the -E option to indicate that the file(s) should just be processed.
When we see #include <iostream>, it is said to be a preprocessor directive.
#include ---> directive
And, I think:
<iostream> ---> preprocessor
But, what is meant by "preprocessor" and "directive"?
It may help to think of the relationship between a "directive" and being "given directions" (i.e. orders). "preprocessor directives" are directions to the preprocessor about changes it should make to the code before the later stages of compilation kick in.
But, what's the preprocessor? Well, its name reflects that it processes the source code before the "main" stages of compilation. It's simply there to process the textual source code, modifying it in various ways. The preprocessor doesn't even understand the tokens it operates on - it has no notion of types or variables, classes or functions - it's all just quoted- and/or parentheses- grouped, comma- and/or whitespace separated text to be manhandled. This extra process gives more flexibility in selecting, combining and even generating parts of the program.
EDIT addressing #SWEngineer's comment: Many people find it helpful to think of the preprocessor as a separate program that modifies the C++ program, then gives its output to the "real" C++ compiler (this is pretty much the way it used to be). When the preprocessor sees #include <iostream> it thinks "ahhha - this is something I understand, I'm going to take care of this and not just pass it through blindly to the C++ compiler". So, it searches a number of directories (some standard ones like /usr/include and wherever the compiler installed its own headers, as well as others specified using -I on the command line) looking for a file called "iostream". When it finds it, it then replaces the line in the input program saying "#include " with the complete contents of the file called "iostream", adding the result to the output. BUT, it then moves to the first line it read from the "iostream" file, looking for more directives that it understands.
So, the preprocessor is very simple. It can understand #include, #define, #if/#elif/#endif, #ifdef and $ifndef, #warning and #error, but not much else. It doesn't have a clue what an "int" is, a template, a class, or any of that "real" C++ stuff. It's more like some automated editor that cuts and pastes parts of files and code around, preparing the program that the C++ compiler proper will eventually see and process. The preprocessor is still very useful, because it knows how to find parts of the program in all those different directories (the next stage in compilation doesn't need to know anything about that), and it can remove code that might work on some other computer system but wouldn't be valid on the one in use. It can also allow the program to use short, concise macro statements that generate a lot of real C++ code, making the program more manageable.
#include is the preprocessor directive, <iostream> is just an argument supplied in addition to this directive, which in this case happens to be a file name.
Some preprocessor directives take arguments, some don't, e.g.
#define FOO 1
#ifdef _NDEBUG
....
#else
....
#endif
#warning Untested code !
The common feature is that they all start with #.
In Olden Times the preprocessor was a separate tool which pre-processed source code before passing it to the compiler front-end, performing macro substitutions and including header files, etc. These days the pre-processor is usually an integral part of the compiler, but it essentially just does the same job.
Preprocessor directives, such as #define and #ifdef, are typically used to make source programs easy to change and easy to compile in different execution environments. Directives in the source file tell the preprocessor to perform specific actions. For example, the preprocessor can replace tokens in the text, insert the contents of other files into the source file...
#include is a preprocessor directive meaning that it is use by the preprocessor part of the compiler. This happens 'before' the compilation process. The #include needs to specify 'what' to include, this is supplied by the argument iostream. This tells the preprocessor to include the file iostream.h.
More information:
Preprocessor Directives on MSDN
Preprocessor directives on cplusplus.com