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".
Related
I'm writing a simple build file with bash, that is suppose to make it easy for me to switch entry point by emulating Python's
if __name__ == '__main__':
main()
My idea was to include a macro by passing -D __MAIN__=\"$MAIN_FILE\" to clang++, where MAIN_FILE is a file you specify when running the build script. Then I'll just have to compare the macro __MAIN__ to the predefined standard macro __FILE__ for each source file. Something like this:
#if equals(__FILE__, __MAIN__)
int main()
{
/* code */
return 0;
}
#endif
The problem I'm encountering is making the function equals to work in compile-time. Reading up on this it seems like it should be possible to define a constexpr function that compares the strings in compile-time (at least according to this and this answer).
However, whenever I try to create such a function (or copying the code from here or here), I get the following error:
error: function-like macro 'equals' is not defined
Which seems strange to me since it's neither a macro or undefined. I couldn't find a solution when searching for the error message either.
Here's the full code for reference:
#include <iostream>
constexpr bool equals(const char* a, const char* b)
{
return *a == *b && (*a == '\0' || equals(a + 1, b + 1));
}
#if equals(__FILE__, __MAIN__)
int main()
{
std::cout << "Running " << __MAIN__ << std::endl;
return 0;
}
#endif
Compiled with:
clang++ main.cpp -std=c++14 -D __MAIN__="fullpath/main.cpp"
What's causing this error and how can I solve my problem?
#if and #endif are preprocessor directives - the preprocessor runs as part of the compilation step, but it is not aware about C++ as a language.
You cannot mix and match the preprocessor with C++ features such as constexpr functions.
If you want this to work, you need to implement your own #define EQUALS macro that checks string equality entirely in the preprocessing step. I'm not sure whether or not it's possible (and worth it).
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.
I want to get full function path and declaration in code via macro or some compiler magic. I have this code (click here to run):
#include <iostream>
namespace NS {
struct Foo {
static int sum(int a, int b) {
std::cout << "This is from " << __FILE__ << ":" << __LINE__ << " # " << __func__ << std::endl;
return a+b;
}
static int sum(int a, int b, int c) {
std::cout << "This is from " << __FILE__ << ":" << __LINE__ << " # " << __func__ << std::endl;
return a+b+c;
}
};
}
int main() {
NS::Foo::sum(1,2);
NS::Foo::sum(1,2, 3);
}
And I get the output:
This is from /some/where/main.cpp:7 # sum
This is from /some/where/main.cpp:12 # sum
My questions are:
How do I get the full path of sum function invoked?(NS::Foo::sum)
How can I get the full function declaration with argument types?( sum(int, int) or sum(int, int, int))
I am interested in mainstream compilers: Clang, GCC, Microsoft C++ compiler
Answering for GCC.
Checkout the __PRETTY_FUNCTION__ macro. I've found it in the defintion of assert macro in <assert.h>. Perhaps same could be found for other compilers and libc implementations.
For Microsoft Visual Studio compiler, __FUNCSIG__ can give you a lot about the function.
__FUNCSIG__ will give you full function signature
__FUNCDNAME__ gives magnled name.
__FUNCTION__ is just for function name.
If you don't want to limit yourself to a single compiler, and don't fancy writing a pre-processor ifdef chain yourself, boost has already defined a macro BOOST_CURRENT_FUNCTION which is defined as the full function signature macro that's defined on the used compiler. __PRETTY_FUNCTION__ in gcc and other compilers that support that, __FUNCSIG__ where that is supported (msvc), also supports some lesser used compilers and falls back to __func__ as defined by the C standard (or a static placeholder if even that's not supported).
Given the following code:
1. #include <iostream>
2. #define CALL_FUNC(f) f();
3.
4. int main()
5. {
6. CALL_FUNC([](){
7. std::cout << "I'm on line " << __LINE__ << std::endl;
8. });
9. return 0;
10. }
When I compile this in Visual Studio 2012 and g++ 4.7.3, I get the output "I'm on line 8".
When I compile this in clang, I get the output "I'm on line 7", which is what I expected.
Does anyone know which of these is the correct behavior? Is there a way to get the desired behavior in VS and g++ while still having a CALL_FUNC macro?
The standard does not specify the interaction between macro expansion and the __LINE__ predefined macro. In particular a macro invocation that spans multiple lines and contains a __LINE__ token exhibits different behaviours on different preprocessors. When part of a macro argument that is expanded, some will give it the line number of the enclosing macro head name (6), some the closing parenthesis (8) and some the __LINE__ token line (7). It depends on the algorithm used, and there are several that are valid and standard-conformant.
This can be demonstrated as follows:
#define F(x) x
F(
__LINE__
)
Some preprocessors will output 2, some 3 and some 4.
A quick test seems to show that if you move the }); up a line it works:
std::cout << "I'm on line " << __LINE__ << std::endl;});
gcc and msvc seem to think it is on the next line because of the }); on the next line.
(Also, you have an extra semi-colon BTW).
#include <iostream>
#include <string>
#include <vector>
extern "C"{
#include "sql.c"
}
class ReportsSync{
public:
string getQuery();
bool testQuery(string);
};
if i have a cpp file like tis, rather a .h file like this, wud i be able to call functions defines in sql.c as usual, like i am calling c++ functions?
for eg: if sql.c has a function named foo, which returns a datatype defines in sql.c itself, can i use the returned datatype inside maybe the testQuery(), manipulate it or give it to the next function?
For #include directives the preprocessor does just a text replacement. It is like you copy all text from sql.c to your source file.
So yes you can call the functions defined in sql.c.
The only thing I know of where care is required is if your C functions take function pointers as parameters to provide a callback. You should not throw exceptions in such a callback because C does not know about C++ exceptions.
However as already pointed out in the comments it is more common to #include header files. So you can use the functions of sql.h in more than one compilation unit (.c file).
Just one thing (too large to put in a comment).
Adding extern "C" { <SOMETHING> } to a C++ source does not automagically make that SOMETHING C. It is still C++, but the interface from that SOMETHING follows C rules instead of C++ rules.
#ifndef __cplusplus
/* plain old C */
int y(void) {
return sizeof 'a';
}
#else
/* C++ */
#include <iostream>
extern "C" {
int y(); /* y is defined above, compiled with a C compiler */
int x() {
return sizeof 'a';
}
}
int main() {
std::cout << "regular sizeof 'a' is " << sizeof 'a' << std::endl;
std::cout << "extern \"C\" sizeof 'a' is " << x() << std::endl;
std::cout << "plain old C sizeof 'a' is " << y() << std::endl;
}
#endif
Compilation for the program above saved as "c++c.src" and test run
$ gcc -std=c89 -pedantic -c -xc c++c.src -o y.o
$ g++ y.o -pedantic -xc++ c++c.src
$ ./a.out
regular sizeof 'a' is 1
extern "C" sizeof 'a' is 1
plain old C sizeof 'a' is 4