I am learning C++ macro. And now I am totally confused. So help me! Below is my code, what I am trying to do is to use the C++ macro and call different functions using "template" such that I could only write one function and this function can be used to do the same things for different types. But when I compile this code, it throws the following errors.
testCPP.cpp: In function 'void test_int_Macro(int)':
testCPP.cpp:14: error: a function-definition is not allowed here before '{' token
testCPP.cpp:26: error: expected `}' at end of input**
#include<iostream>
#include<cstdint>
using namespace std;
#define Query_Data(Type)\
void test_##Type##_Macro(Type data){ \
cout<<"Test: "<<sizeof(data)<<" "<<endl; \
//cout<<"Type is "<<##Type##<<endl;\
}
Query_Data(int)
Query_Data(char)
int main(){
cout<<sizeof(unsigned)<<endl;
cout<<sizeof(char)<<endl;
cout<<sizeof(int32_t)<<endl;
int num=6;
char c='a';
Query_Data(num);
//Query_Data(c);
}
In C++, macros are very simple and stupid. The proeprocessor simply regurgitates whatever the macro is defined to be wherever you invoke it.
If you do the preprocessing on a piece of paper, what you come up with is:
int main(){
cout<<sizeof(unsigned)<<endl;
cout<<sizeof(char)<<endl;
cout<<sizeof(int32_t)<<endl;
int num=6;
char c='a';
void test_num_Macro(Type data){
cout<<"Test: "<<sizeof(data)<<" "<<endl;
//cout<<"Type is "<<##Type##<<endl;
}
}
The compiler gave you an error message which in this case was spot-on:
testCPP.cpp:14: error: a function-definition is not allowed here before '{' token
Look at the main function you end up with as a result of the preprocessing. It has a function declared within it. That, obviously, isn't allowed.
Now, if we follow this train of thought to the next logical stage, the question becomes "so how do I achieve what I'm trying to achineve?"
You said that:
what I am trying to do is to use the C++ macro and call different
functions using "template" such that I could only write one function
and this function can be used to do the same things for different
types.
And there is a facility in C++ for exactly this. Coincidentally, they are called templates. Here's how you might use one here:
template <typename Val>
void test ()
{
cout << "Test: " << sizeof (Val) << " " << endl;
}
int main(){
cout<<sizeof(unsigned)<<endl;
cout<<sizeof(char)<<endl;
cout<<sizeof(int32_t)<<endl;
int num=6;
char c='a';
test <char> ();
test <int> ();
}
Macros are a cludge. The are not sophisticated, they skirt around the C++ type system, they are very hard to debug and maintain. It is generally advised to avoid using them unless you have no other choice. There are places when you do have no other choice -- but this isn't one of them.
John Dibling is quite right. But I would like to point out that the easiest way to debug preprocessor issues is usually by running g++ -E src.cpp which shows you the file after it's been preprocessed. (remove your #include's first or you'll get way too much output)
And the reason for the the "expects '}' at end of input" error is that commented line in your macro. The preprocessor treats it as an empty line (without a trailing ) and so doesn't look farther and leaves your '}' out of the define.
You should avoid using the preprocessor in C++ for anything but #include and include guards in header files.
Macros are simple text replacement snippets, so you will end up defining those functions inside main function, a thing you cannot do in C++. You can see it very well if you run your code through the preprocessor:
void test_int_Macro(int data){ cout<<"Test: "<<sizeof(data)<<" "<<endl;
void test_char_Macro(char data){ cout<<"Test: "<<sizeof(data)<<" "<<endl;
int main(){
cout<<sizeof(unsigned)<<endl;
cout<<sizeof(char)<<endl;
cout<<sizeof(int32_t)<<endl;
int num=6;
char c='a';
void test_num_Macro(num data){ cout<<"Test: "<<sizeof(data)<<" "<<endl;;
}
Thus said, you should (and probably, you already got it) use templates:
template <class Type>
void Query_Data(Type data) {
std::cout << "Test: " << sizeof(data) << " " << std::endl;
}
If you wish, you can specialize the template for specific types like:
template<>
void Query_Data<int>(int data) {
std::cout << "This is an integer!" << std::endl;
}
and use them as intended:
int main(){
cout<<sizeof(unsigned)<<endl;
cout<<sizeof(char)<<endl;
cout<<sizeof(int32_t)<<endl;
int num=6;
char c='a';
Query_Data(num);
Query_Data(c);
}
Related
I discovered this in the source code for the Unreal Engine 4 and didn't recognize it. The specific instance of it is:
#undef UCLASS
#define UCLASS(...) \
ARadialForceActor_EVENTPARM
I'm a fairly new programmer and this kind of macro is unfamiliar to me. My guess was that it is defining a macro that will take every overloaded version of the function UCLASS (in other words, every instance of a function named UCLASS, regardless of the type and number of parameters) and replace it with the variable ARadialForceActor_EVENTPARM. Is that correct? If not, does anyone know what it means? I tried writing a code snippet to test this, but it returned error: "." may not appear in macro parameter list. I'll include it below, in case I was right about the macro, in which case I would appreciate it if someone could point out where I went wrong in my code:
#include <iostream>
#define foo( . . . ) bar
using namespace std;
int foo() {cout <<54321<<endl;}
int main()
{ bar=12345;
cout<<bar<<endl;
return 0;
}
Your guess of the meaning of #define foo(...) bar is correct. Your error is in thinking that . . . and ... are the same; they are not. ... must be written with no spaces between the dots. If I modify your program to read
#include <iostream>
#define foo(...) bar
using std::cout;
int foo()
{
cout << 54321 << '\n';
}
int main()
{
bar = 12345;
cout << bar << '\n';
return 0;
}
(please take note of other stylistic corrections; future readers of your code will thank you)
then I get error messages consistent with foo() having been replaced with bar in the function definition, as if you had written
int bar
{
cout << 54321 << '\n';
}
which is, in fact, what this tells the preprocessor to do. (The preprocessor, as always, has no understanding of the syntax of the language proper.)
#define FOO(...)
this means your macro can accept variable number of arguments. See here for details.
Hi I am new to C++ and testing a structure in a c++ code in dev-c++. but it is not compiling and giving errors .
It is working well with .h extensions in pre-processor directives in dev-c++. so i Dont think so it carries .h extension problems
#include<iostream.h>
#include<conio.h>
#include<iomanip.h>
struct car
{
const int MAX=10;
char model[MAX];
char spare_part[MAX];
float cost;
}
int main()
{
car BMW ;
BMW.model[MAX]="SLR-8 S";
BMW.spare_part[MAX]="SILENCER";
BMW.cost=175.56F;
cout << setw(50) << "\n\n WELCOME TO SHOWROOM" << endl << endl;
cout << "CAR MODEL: " << BMW.model[MAX] << endl;
cout << "SPARE PART: " << BMW.spare_part[MAX] << endl;
cout << "COST OF PRODUCT: " << BMW.cost[MAX] << endl;
return 0;
}
Compiler logs are:
Compiler: Default compiler
Executing g++.exe...
g++.exe "D:\cdev\projects\structure.cpp" -o "D:\cdev\projects\structure.exe" -I"D:\cdev\Dev-Cpp\lib\gcc\mingw32\3.4.2\include" -I"D:\cdev\Dev-Cpp\include\c++\3.4.2\backward" -I"D:\cdev\Dev-Cpp\include\c++\3.4.2\mingw32" -I"D:\cdev\Dev-Cpp\include\c++\3.4.2" -I"D:\cdev\Dev-Cpp\include" -L"D:\cdev\Dev-Cpp\lib"
In file included from D:/cdev/Dev-Cpp/include/c++/3.4.2/backward/iostream.h:31,
from D:\cdev\projects\structure.cpp:1:
D:/cdev/Dev-Cpp/include/c++/3.4.2/backward/backward_warning.h:32:2: warning: #warning This file includes at least one deprecated or antiquated header. Please consider using one of the 32 headers found in section 17.4.1.2 of the C++ standard. Examples include substituting the <X> header for the <X.h> header for C++ includes, or <iostream> instead of the deprecated header <iostream.h>. To disable this warning use -Wno-deprecated.
D:\cdev\projects\structure.cpp:6: error: ISO C++ forbids initialization of member `MAX'
D:\cdev\projects\structure.cpp:6: error: making `MAX' static
D:\cdev\projects\structure.cpp:13: error: new types may not be defined in a return type
D:\cdev\projects\structure.cpp:13: error: extraneous `int' ignored
D:\cdev\projects\structure.cpp:13: error: `main' must return `int'
D:\cdev\projects\structure.cpp: In function `int main(...)':
D:\cdev\projects\structure.cpp:16: error: `MAX' undeclared (first use this function)
D:\cdev\projects\structure.cpp:16: error: (Each undeclared identifier is reported only
once for each function it appears in.)
Execution terminated
Values in stuct should be initialized in a constructor, or should be static. Like:
struct car
{
static const int MAX=10;
...
There is a semicolon missing after the struct definition. It should be like:
struct car
{
static const int MAX=10;
char model[MAX];
char spare_part[MAX];
float cost;
};
Check your semicolons. One is required after the closing } of the struct.
Also, declare the MAX variable static, i.e.
{
static const int MAX=10;
but the compiler tells you that one quite nicely...
And the third error comes from the fact that you declare MAX inside car, you'd have to reference it accordingly as car::MAX. But actually, the whole BMW.model[MAX]="SLR-8 S"; statement doesn't really make sense. That would mean 'assign the string "SLR-8 S" to the character after the last one in BMW.model' (for a char[MAX], the valid indices start at 0, and go to (MAX-1)!). Best use std::string instead of char model[MAX], that's by far easier to handle! E.g.:
struct car
{
std::string model;
Then you can simply say
BMW.model="SLR-8 S";
A bit of background: I want to write a tool that compiles a bunch of named things into C++ code. The list changes and I don't want to rebuild the world when that happens. Despite that, I want to address the compiled code by (literal) name.
As an example of something that's not quite right, I could have put this in a header:
template<int name> void func();
Then my tool can generate code like:
template<> void func<1>() { ... }
template<> void func<2>() { ... }
template<> void func<3>() { ... }
Now I can call these by "name" anywhere without pre-declaring each one.
I want to do this, but with something more descriptive than integers. Ideally I want text of some form. What I need is something like:
#define FUNC_WITH_NAME(name) func_named_ ## name
That doesn't quite work, though: it needs a declaration of func_named_whatever.
The next try is no good either (and it's GCC-specific):
#define FUNC_WITH_NAME(name) ({extern void func_named_ ## name; func_named_ ## name;})
It fails because, if it's used inside a namespace, then it ends up looking for func_named_whatever in that namespace.
The best I've come up with is this:
template<char... tagchars> int tagged();
namespace NS {
int caller()
{
return tagged<'n', 'a', 'm', 'e'>();
}
}
This works, but it's ugly (and it's not obvious how to turn a string literal into a parameter pack without jumping through nasty hoops). Also, if the symbol doesn't resolve, then the error message from g++ is terrible:
In function `NS::caller()':
named_symbol.cpp:(.text+0x5): undefined reference to `int tagged<(char)110, (char)97, (char)109, (char)101>()'
collect2: error: ld returned 1 exit status
The only thing that I've come up with is a gcc extension:
extern void func_named_whatever __asm__("func_named_whatever");
But this is no good as a template argument (it only affects calls to that function; it does not affect use of magic asm-ified symbols when they're template arguments), and it defeats any link-time type checking because it turns off mangling.
Now I can call these by "name" anywhere without pre-declaring each one.
To call any function at compile time, you need to forward-declare it.
Because you want to call them at compile time, there's no need to use string literals. And you can only do this using preprocessor, not templates, because you cannot specify identifier names for templates (in C++03, at least).
Example:
#include <iostream>
#define CALL_FUNC(func, args) name_ ##func args;
void name_func1(){
std::cout << "func1" << std::endl;
}
void name_func2(int a){
std::cout << "func2:" << a << std::endl;
}
int main(int argc, char** argv){
CALL_FUNC(func1, ());
CALL_FUNC(func2, (46));
return 0;
}
You can forward-declare function within function body:
#include <iostream>
int main(int argc, char** argv){
void name_func(int);
name_func(42);
return 0;
}
void name_func(int arg){
std::cout << "func1:" << arg << std::endl;
}
So, technically, you don't even need to use preprocessor for that.
You cannot avoid forward-declaration, unless all functions arguments are known as well as their types, in which case you can hide forward-declaration with macros.
#include <iostream>
#define FUNC_NAME(func) name_ ##func
#define CALL_VOID_FUNC(func) { void FUNC_NAME(func)(); FUNC_NAME(func)(); }
int main(int argc, char** argv){
CALL_VOID_FUNC(func1);//not forward declared
return 0;
}
void name_func1(){
std::cout << "func1" << std::endl;
}
Or if you want to specify function argument types every time you call functions and know number of arguments:
#include <iostream>
#define FUNC_NAME(func) name_ ##func
#define CALL_FUNC_1ARG(func, type1, arg1) { void FUNC_NAME(func)(type1); FUNC_NAME(func)(arg1); }
int main(int argc, char** argv){
CALL_FUNC_1ARG(func1, int, 42);
return 0;
}
void name_func1(int arg){
std::cout << "func1:" << arg << std::endl;
}
Or if your function can take variable number of arguments. (parsing varargs is fun):
#include <iostream>
#define FUNC_NAME(func) name_ ##func
#define CALL_FUNC_VARIADIC(func, args) { void FUNC_NAME(func)(...); FUNC_NAME(func)args; }
int main(int argc, char** argv){
CALL_FUNC_VARIADIC(func1, (42, 43, 44));
return 0;
}
void name_func1(...){
//std::cout << "func1:" << arg << std::endl;
}
If you want to use STRINGS (as in "func1"), then you are trying to locate function at run time, not at compile time, even if you don't really think so. That's because "funcname" isn't that different from (std::string(std::string("func") + std::string("name")).c_str()) - it is pointer to memory region with character. Some compiler might provide extensions to "unstringize" string, but I'm not aware of such extensions.
In this case your only option is to write either preprocessor or code-generator, that'll scan some kind of text template (that lists functions) every time you build the project, and converts it into .h/.cpp files that are then compiled into your project. Those .h/.cpp files shoudl build function table (name to function pointer map) that is then used "behind the scenes" in your project. See Qt MOC for a working example. That'll require recompilation every time you add new function to template.
If you do not want recompilation for every new function prototype (although you can't add call to a new function without recompiling project, obviously), then your only choice is to embed scripting language into your application. This way you'll be able to add functions without recompiling. At we momen, you can embed lua, python, lisp(via ecl) and other languages. There's also working C++ interpreter, although I doubt it is embeddable.
If you do not want to use any options I listed, then (AFAIK) you cannot do that at all. Drop some requirement ("no recompilation", "no forward declaration", "call using string literal") and try again.
Can I reliably turn a string literal into a symbol name using the C macro language?
No. You can turn string literal into identifier to be processed by compiler (using stringize), but if compiler doesn't know this identifier at this point of compilation, your code won't compile. So, if you're going to call functions this way using their names, then you'll have to insure that they all were forward-declared before. And you won't be able to locate them at runtime.
C++ doesn't store names for functions and variables in compiled code. So you can't find compiled function by its name. This is because C++ linker is free to eliminate unused functions completely, inline them or create multiple copies.
What you CAN do:
Create a table of functions that you want to address by name (that maps function name to function pointer), then use this table to locate functions. You'll have to manually register every function you want to be able to find in this table. Something like this:
typedef std::string FunctionName;
typedef void(*Function)(int arg);
typedef std::map<FunctionName, Function> FunctionMap;
FunctionMap globalFunctionMap;
void callFunction(const std::string &name, int arg){
FunctionMap::iterator found = globalFunctionMap.find(name);
if (found == globalFunctionMap.end()){
//could not find function
return;
}
(*found->second)(arg);
}
Use dynamic/shared libraries. Put functions you want to be able to address into shared library (extern "C" __declspec(dllexport) or __declspec(dllexport)), mark them for export then use operating system functions to locate function within library (dlsym on linux, GetProcAddress of windows). Afaik, you might be able export functions from exe as well, so you might be able to use this approach without additional dlls.
Embed scripting language into your application. Basically, in most scripting languages you can locate and call function by its name. That'll be function declared within scripting language, obviously, not a C++ function.
Write code preprocessor that'll scan your project for "named" functions and build table of those function (method #1) somewhere automatically. Can be very difficult, because C++ is not that easy to parse.
The ideal solution would be N3413, but that's a long way off.
With thanks to 0x499602d2 and Using strings in C++ template metaprograms, here's a so-so answer:
template<char... str>
struct tag
{
template<char first>
struct prepend
{
typedef tag<first, str...> type;
};
};
template<typename Tag>
void func();
#define PREPARE_STR_TAGGER(str) \
template<int charsleft> \
struct tagger_for_##str \
{ \
typedef typename \
tagger_for_##str<charsleft-1>::type:: \
template prepend<(#str)[sizeof(#str)-1-charsleft]>::type type; \
}; \
template<> \
struct tagger_for_##str<0> \
{ \
typedef tag<> type; \
};
#define STRING_TO_TAG(str) tagger_for_##str<sizeof(#str)-1>::type
namespace SHOULD_NOT_MATTER {
PREPARE_STR_TAGGER(some_string);
void test()
{
func<STRING_TO_TAG(some_string)>();
}
}
Downsides:
It's awkward to use: you need to use PREPARE_STR_TAGGER at namespace (or maybe class) scope.
It's probably unfriendly to compile time.
The linker errors it generates are awful.
Some kind of decent hash function based on constexpr would work, but it would result in even more awful error messages.
Improvements are welcome.
I know that defines in the beginning of a C++ file are Preprocessor directives so "the preprocessor is executed before the actual compilation of code begins, therefore the preprocessor digests all these directives before any code is generated by the statements [1]".
Now what if I have this simple example:
#define PRINT(function) printFnctionName(#function)
void printFnctionName(string name)
{
cout << name;
}
void test(){};
int main(int argc, char *argv[])
{
PRINT(test);
}
So now my question is really how does the precompiler know what function will be passed in? and how is the pre-compilation/linking/compilation really happening?
Also, the reason I am using define and not a regular function, it is because I wasn't able to find a way to replicate this functionality `#function to retrieve the name of a function
So now my question is really how does the precompiler know what
function will be passed in? and how is the
pre-compilation/linking/compilation really happening?
Preprocessor doesn't know about anything. It simply replaces the text with the defined value and stringifies the value you passed in.
So the compiler sees it:
void printFnctionName(string name)
{
cout << name;
}
void test(){};
int main(int argc, char *argv[])
{
printFnctionName("test");
}
The preprocessor does text substitution. In your case, your code will be transformed to:
int main(int argc, char *argv[])
{
printFnctionName("test");
}
by the preprocessor before the rest of the compiling process kicks in. Some preprocessor directives are simple, other much more complicated (variable arity preprocessor directives, for instance).
Of course, it requires that you have included the correct header file etc.
For this particular case, there are two parts to the answer. One part is that C preprocessor knows nothing about what function is being called, it simply does the textual replacement.
The second part is the "stringifier", #function actually replaces test as an input to PRINT with "test". Of course, it doesn't have to be a function - just because it's called printfunction, you could do:
PRINT(a+b);
and you'd get the code:
printFnctionName("a+b");
or
PRINT(a-*&1,78^%j)
and get:
printFnctionName("a-*&1,78^%j");
[Why is the u missining in printFnctionName?]
The stringification operator is very useful if you have something like
#define ASSERT(x) do { if (!x) fail_assert(#x, __FILE__, __LINE__); } while(0)
void fail_assert(const char *expr, const char *file, int line)
{
cerr << "Assertion (" << expr << ") failed at " << file << ":" << line << endl;
}
....
ASSERT(ptr != NULL);
Now you get an error message "Assertion failed (ptr != NULL) at myprog.cpp:112", which can be quite useful.
I am new to templates in c++.
i was trying some small programs.
CPP [80]> cat 000001.cpp 000001.hpp
#include <iostream>
#include <string>
#include "000001.hpp"
int main()
{
int i = 42;
std::cout << "max(7,i): " << ::max(7,i) << std::endl;
double f1 = 3.4;
double f2 = -6.7;
std::cout << "max(f1,f2): " << ::max(f1,f2) << std::endl;
std::string s1 = "mathematics";
std::string s2 = "math";
std::cout << "max(s1,s2): " << ::max(s1,s2) << std::endl;
}
template <typename T>
inline T const& max (T const& a, T const& b)
{
return a < b ? b : a;
}
when i compile this program:
i get an error below:
CPP [78]> /opt/aCC/bin/aCC -AA 000001.cpp
Error (future) 229: "/opt/aCC/include_std/string.cc", line 164 # "Ambiguous overloaded function call; a
function match was not found that was strictly best for ALL arguments. Two functions that matched
best for some arguments (but not all) were "const unsigned long &max<unsigned long>(const unsigned
long &,const unsigned long &)" ["000001.hpp", line 2] and "const unsigned long &std::max<unsigned
long>(const unsigned long &,const unsigned long &)" ["/opt/aCC/include_std/algorithm", line 1762]."
Choosing "const unsigned long &max<unsigned long>(const unsigned long &,const unsigned long &)"
["000001.hpp", line 2] for resolving ambiguity.
_C_data = _C_getRep (max (_RW::__rw_new_capacity (0, this),
^^^
Warning: 1 future errors were detected and ignored. Add a '+p' option to detect and fix them before they become fatal errors in a future release. Behavior of this ill-formed program is not guaranteed to match that of a well-formed program
Could nybody please tell me what exactly the error is?
You are probably including <iostream.h> instead of <iostream> somewhere. The former hasn't existed for some time now, but for compatibility reasons, you compiler still accepts the include and replaces it with
#include <iostream>
using namespace std;
This causes std::max to be brought to the global namespace, thus resulting in an ambiguity. Replace <iostream.h> with <iostream> or rename your max function and the problem should disappear.
Edit: You've apparently fixed the include, but I bet you still have using namespace std; somewhere. You need to get rid of that. In fact you should never use using namespace in the global scope.
Edit: You might also have using std::max somewhere. You need to get rid of it too.
The code you've posted compiles just fine, there must be something else that is wrong inside "000001.hpp". Can you post the contents of that file too?
Edit: If you do as avakar says but the problem persists, that must be due to some problem with your compiler. There are two obvious workarounds I can think of: rename your max function to something else, or put it in a namespace:
namespace Foo
{
template <typename T>
inline T const& max (T const& a, T const& b)
{
return a < b ? b : a;
}
}
int main()
{
int i = 42;
std::cout << "max(7,i): " << Foo::max(7,i) << std::endl;
double f1 = 3.4;
double f2 = -6.7;
std::cout << "max(f1,f2): " << Foo::max(f1,f2) << std::endl;
std::string s1 = "mathematics";
std::string s2 = "math";
std::cout << "max(s1,s2): " << Foo::max(s1,s2) << std::endl;
}
I don't know which compiler you are using but the second error tells you that the two following functions are clashing :
::max
std::max
It seems really weird, you may have a using namespace std; somewhere or worse, that one of your include use iostream.h as noted in the first error. Could you give more information about your compiler/toolchain and the content of your .hpp file?
It says that two definitions for
max<unsigned long>
were found. One definition is in 000001.hpp and the other is in /opt/aCC/include_std/algorithm. The compiler chose the one in 000001.hpp for now, so no error is present now. But it says that these two definitions may cause errors in the future.
I don't know if this causes the problem, but anyhow; you shouldnt use the name max for your global (or local) function as it is a part of STL.