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.
Related
In C++ I'm not sure if I'm supposed to add a semi-colon at the end of a include statement or not.
For example, to use the std::cout method you must include the iostream library, like this:
#include <iostream>
After I include the <iostream> library should I add semi-colon at the end of the statement, like this:
#include <iostream>;
Or just leave it be?
No you shouldn't.
Why?
#xxxxxx are preprocessor directives. The former are part of a separate step in the compilation process. The preprocessor analyses the code before the actual compilation of code starts. All the directives are resolved before actual code is generated by normal C++ statements.
Summary:
Most C/C++ statements need to be ended with a semicolon ;. It's part of the C/C++ standard.
Preprocessor directives do not need to be ended by a ; or any other symbol.
If the content of the include file is syntactically correct, the semicolon will have no effect at all. So why should you add it? Redundant code like this typically causes confusion and leads to bad maintainability.
In the unlikely case that a semicolon is missing after the last statement of your include file, this error would be 'fixed' by adding the semicolon. But this is by no means a good thing because such an error should be fixed in the include file itself. Otherwise it will lead to even more confusion.
While researching solutions to the windows min/max macro problem, I found an answer that I really like but I do not understand why it works. Is there something within the C++ specification that says that macro substitution doesn't occur within parens? If so where is that? Is this just a side effect of something else or is the language designed to work that way? If I use extra parens the max macro doesn't cause a problem:
(std::numeric_limits<int>::max)()
I'm working in a large scale MFC project, and there are some windows libraries that use those macros so I'd prefer not to use the #undef trick.
My other question is this. Does #undef max within a .cpp file only affect the file that it is used within, or would it undefine max for other compilation units?
Function-like macros only expand when the next thing after is an opening parenthesis. When surrounding the name with parentheses, the next thing after the name is a closing parenthesis, so no expansion occurs.
From C++11 § 16.3 [cpp.replace]/10:
Each subsequent instance of the function-like macro name followed by a ( as the next preprocessing token introduces the sequence of preprocessing tokens that is replaced by the replacement list in the definition (an invocation of the macro).
To answer the other question, preprocessing happens before normal compilation and linking, so doing an #undef in an implementation file will only affect that file. In a header, it affects every file that includes that header.
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.
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
A hypothetical question: Is it possible to have a C++ program, which includes preprocessor directives, entirely on one line?
Such a line would look like this:
#define foo #ifdef foo #define bar #endif
What are the semantics of such a line?
Further, are there any combinations of directives which are impossible to construct on one line?
If this is compiler-specific then both VC++ and GCC answers are welcome.
A preprocessing directive must be terminated by a newline, so this is actually a single preprocessing directive that defines an object-like macro, named foo, that expands to the following token sequence:
# ifdef foo # define bar # endif
Any later use of the name foo in the source (until it is #undefed) will expand to this, but after the macro is expanded, the resulting tokens are not evaluated as a preprocessing directive.
This is not compiler-specific; this behavior is defined by the C and C++ standards.
Preprocessor directives are somewhat different than language statements, which are terminated by ; and use whitespace to delimit tokens. In the case of the preprocessor, the directive is terminated by a newline so it's impossible to do what you're attempting using the C++ language itself.
One way you could kind of simulate this is to put your desired lines into a separate header file and then #include it where you want. The separate header still has to have each directive on one line, but the point where you include it is just a single line, effectively doing what you asked.
Another way to accomplish something like that is to have a pre-C++ file that you use an external process to process into a C++ source file prior to compiling with your C++ compiler. This is probably rather more trouble than it's worth.