Pre-processor parsing on C++ - c++

If we want to use user input to do something in a program, or print a result we need to
#include <iostream>
otherwise, cout and cin will not be acknowledged by the compiler.However the command #include is a pre-processor command. And when I was writing my program the following happened. I wrote the following code :
#define PRINT_DEBUG_INFO(a) {cout << “Info: ” << a << endl;}
#include <iostream>
And no errors popped up.How is it possible to use cout before including iostream? Even if I declare the PRINT_DEBUG_INFO(a) without including iostream, I don't get a compiling error.
Can somebody explain me why this happens?

The preprocessor doesn't require any C++ declared symbols to be evaluated to do its work.
It's pure text processing, so defining a macro like
#define PRINT_DEBUG_INFO(a) {cout << “Info: ” << a << endl;}
and expanding it like
#include <iostream>
void foo {
int a = 5;
PRINT_DEBUG_INFO(a);
}
will become
// All the literal stuff appearing in <iostream>
void foo {
int a = 5;
{cout << “Info: ” << a << endl;};
}
So there's nothing checked regarding proper C++ syntax during definition or expansion of the macro.
These statements will be processed further by the C++ compiler, which will complain about cout isn't declared in the global scope.
To fix this, declare your macro like
#define PRINT_DEBUG_INFO(a) {std::cout << “Info: ” << a << std::endl;}

You define PRINT_DEBUG_INFO but you don't use it so there is nothing for the compiler to compile or complain about.

You are just defining PRINT_DEBUG_INFO(a) and not using it. When you actually use it inside your program you will get the error that cout is not defined.
When you are not actually using it, the compiler finds no place to substitute the defined constant. When you actually use it, the program gets expanded during compilation and shows you the error.
And moreover there is a bracket in your macro which gets expanded with brackets and may lead to error.

Related

Have I found a bug in Clang and GCC?

main.cpp:
#include <iostream>
struct Cls {
static void some_method() {
std::cout << __FILE__ << ": " << __LINE__ << std::endl;
}
};
extern void call_some_method();
void never_caled() {
Cls::some_method(); // (1)
}
int main() {
call_some_method();
return 0;
}
cls.cpp:
#include <iostream>
struct Cls {
static void some_method() {
std::cout << __FILE__ << ": " << __LINE__ << std::endl;
}
};
void call_some_method() {
Cls::some_method();
}
When (1) is commented, call_some_method() write "/home/maxim/CLionProjects/bug/cls.cpp: 5" to std::cout.
When (1) is uncommented, call_some_method() write "/home/maxim/CLionProjects/bug/main.cpp: 5" to std::cout.
How it can be possible for different outputs?
__FILE__ and __LINE__ are macros that are expanded by the pre-processor. Since those macros are in different files, and depend on the files they are used in, they expand to different token sequences.
That means that your definition of Cls::some_method is different across different translation units. This violates the one-definition-rule (ODR) which requires, among other things, that there be exactly one definition of a particular entity in your entire program. If there are multiple definitions, that's fine, so long as the token sequence of those definitions is identical in every translation unit, and those tokens mean the same thing when they are parsed.
This is obviously not true in your case, so you are violating the ODR, which makes the program ill-formed (No Diagnosis Required). This means the compiler is not obliged to give you an error, but if it does produce a program, executing that program invokes undefined behavior (UB). So your program could do anything at all, including producing the output that you are seeing.

Is it possible to replace the whole line with #define?

Let's assume that I have a program with many files and many cout's, and for debug purposes I would like to disable output for a moment, but only in a single file.
It is just out of curiosity question, I know that I shouldn't do that to disable output, but I started to wonder when facing this problem, and it only shows properly what I mean.
I tried to create a #define macro, but I can't replace the whole line, only a single symbol (with params).
For example:
//some common header file
#ifdef DISABLE_OUTPUT
#define cout... void; //?? DK exactly what should i put here
#endif
//other file
#include "commons.h" //my macro
#define DISABLE_OUTPUT
void foo()
{
...
cout << "blablabla" << 4 << "something" << endl; // should be removed
...
}
If DISABLE_OUTPUT is defined, the whole line should be replaced with void; (better clear the line).
The problem is that I don't know how to clear the whole line with #define.
Is there any "magic" symbol or trick that I can use?
It’s a bad idea to define a macro with the same name as a standard library component, so you shouldn’t #define cout at all. I’m going to assume you #define disableable_cout instead.
The simplest answer would be to define it like this:
#ifdef DISABLE_OUTPUT
#define disableable_cout if (false) cout
#else
#define disableable_cout cout
#endif
And then update the cout line in foo to this:
disableable_cout << "blablabla" << 4 << "something" << endl;
Which would expand to either this:
if (false) cout << "blablabla" << 4 << "something" << endl;
if DISABLE_OUTPUT is defined, or to this:
cout << "blablabla" << 4 << "something" << endl;
if DISABLE_OUTPUT were not defined.
Then, if DISABLE_OUTPUT is defined, the output line is skipped; if not, it will happen.
Alternately, you could require DISABLE_OUTPUT is always defined, to either 0 (don’t disable) or 1 (do disable). Then you could use a single definition, like this:
#define disableable_cout if (!DISABLE_OUTPUT) cout
Note that, either option is fragile, like most macros, but it should work in the typical case.

Mixing inline and macro functions

I've decided to try something. I know macros are evil and should be avoided but wanted to see what's going to happen if I do such a thing.
#include <iostream>
using namespace std;
inline void add(int x, int y) { cout << "Inline: " << x + y << endl; }
#define add(x,y) ( cout << "Macro: " << x + y << endl )
int main()
{
add(3,5);
}
It outputs:
Macro: 8
If I comment out the #define line inline starts working, and the output turns into Inline: 8.
My question is, why compiler decides to use macro function instead of inline. Thank you!
I'm using Linux Mint 18.2, g++ 5.4.0, with no parameters g++ -g t2.cpp -o t2.
Macro substitution is performed via the pre-processor before compilation. Thus the compiler never sees add(3,5) - it only sees the macro expansion.
There is not such thing as "macro function". Compiler (actually preprocessor) just turns main into
int main()
{
( cout << "Macro: " << 3 + 5 << endl );
}
A macro comes to effect at the place it is defined, so the inline function is not replaced by the macro, but your call is replaced before compilation. Also note that a macro is not a function, it tells the preprocessor a pattern of replacing texts.
You can run the following command and see the output file (your.i)
g++ -o your.i -E your.cpp
^
And you'll find the inline function not affected by the macro :)
Option -E for G++ means "preprocess the source file, but don't compile, don't assemble and don't link".

#define directives not working outside main() function

I just started learning C++ today. With previous knowledge in other languages I am doing fine so far, but I am confused about #define directives.
I have this code in my "review" C++ file:
#include <iostream>
#define TEST //object-like macro
#ifdef TEST //if TEST is defined
std::cout << "This works!" << std::endl;
#endif
#ifndef NOT_TEST //if NOT_TEST is NOT defined
std::wcout << "This also works!" << std::endl;
#endif
int main()
{
//program code
}
The above code produces errors, first one being syntax error : mssing ';' before '<<'. When I move the #define/#if directives into the main loop, it works properly:
#include <iostream>
int main()
{
#define TEST //object-like macro
#ifdef TEST //if TEST is defined
std::cout << "This works!" << std::endl;
#endif
#ifndef NOT_TEST //if NOT_TEST is NOT defined
std::wcout << "This also works!" << std::endl;
#endif
}
What about the first block of code is incorrect? based on the tutorial I am using, I thought that was how it was supposed to be formatted?
EDIT: I've updated my code to be more clear.
This has nothing to do with formatting. In fact, C++ files are formatting-agnostic. The problem is that after the pre-processor parses your file, you end up with 2 cout statements outside the main function. In C++ you cannot have standalone statements outside of a function, except for declarations/definitions.
You should understand that compilation of a C++ program is a two-step process. First the preproccessor is executed that transforms the file according to instructions you gave it (those that start with #). Then the C++ compiler is executed on the resulting file.
The “code relating to the preprocessor” here is just the #ifdef/#ifndef (with the condition that follows it immediately) and #endif keywords and, indeed, you can put those wherever you like, since preprocessor doesn’t care about C++ syntax, it performs straightforward string operations.
When the preprocessor runs it plugs your C++ code between #ifdef and #endif into the file, so the effect is the same as if you just had the cout << … line (outside the main function).
So, since TEST is defined and NOT_TEST is not, after the preprocessor did its job you are left with a file that has just two lines:
std::cout << "This works!" << std::endl;
std::wcout << "This also works!" << std::endl;
If you try to compile it, you’ll see that the compiler is not happy, because that’s, obviously, not a valid C++ program.
The Problem is using of cout << out of main function.
If you wanna have any output line you can use #error directive to abort compilation process.

Programmatically determine via ifdef if a label is defined within a Translation Unit

I have the following bit of code, I expect that given cstdio is included that the first line will be printed, however the second line is printed.
What am I doing wrong? is it possible to know if labels such as printf or strncmp or memcpy have been defined in the current translation unit at compile time?
#include <iostream>
#include <cstdio>
int main()
{
#ifdef printf
std::cout << "printf is defined.\n";
#else
std::cout << "printf NOT defined!\n";
#endif
return 0;
}
Is the reason because the preprocessor is run before variables and labels are introduced into the scope/TU?
In short is the following code bogus? :
http://code.google.com/p/cmockery/source/browse/trunk/src/example/calculator.c#35
#ifdef only applies to preprocessor macros, defined with #define, not to symbols like function names and variables. You can imagine the preprocessor as an actual separate preliminary step, like running your code through a perl script, that occurs before the "real" compiler gets a crack at it.
So there is no programmatic way to check whether symbols like printf are defined in the current scope. If you use one and it's not defined, you'll get a compiler error. The normal thing to do is to #include a header file with the required definition in the source file where you reference it, not to write a source file that will adapt itself to different possible sets of headers.
As a hack, and depending on your environment and specific problem, the header file that does define printf (or whatever function you care about) may also contain some preprocessor #defines that you could check for.
You can use the guards from original include files to determine if they were included and, consequently, functions were declared.
For example, <stdio.h> shipped with my MSVS2010 has _INC_STDIO guards. Thus your code should be like:
int main()
{
#ifdef _INC_STDIO
std::cout << "printf is defined.\n";
#else
std::cout << "printf NOT defined!\n";
#endif
return 0;
}
Note that this solution is environment-dependent, so you should create more complicated rules it you are supposed to support more than one build chain.
Their are a large number of symbols in stdio.h which are #defined, and it is imported by cstdio
So you could use
#include <iostream>
#include <cstdio>
int main()
{
#ifdef stdin
std::cout << "printf is defined.\n";
#else
std::cout << "printf NOT defined!\n";
#endif
return 0;
}
WARNING I've looked at the header but not tested.