Can I get the address of an object as a string constant in g++? Example:
struct s { } x;
If &x == 1234, then I need "1234" in my code.
EDIT:
By string constant I meant that I need that constant string at compile- or link-time. I need to embed it in inline assembly code like this:
template < typename U >
struct T {
static int x;
void f () {
asm (".word " some-expression-containing-(&x));
}
};
I don't know a way to construct the mangled name with a preprocessor macro, so I asked this question.
The solution doesn't need to be portable, g++ is sufficient.
The address itself is known at compile- or link-time though, as it would work to examine the assembly output and put in the mangled name into the inline assembly instruction.
I wonder why would you need that... but you can do this:
#include <sstream>
#include <cstddef> //for ptrdiff_t
....
stringstream ss;
ss << reinterpret_cast<ptrdiff_t>(&x);
ss.str() now contains your desired string
edit: If you want to do this compile-time... erm... I'll dare assume it's impossible?
template<class U>
struct T {
static int x;
void f () {
asm (".word %0" : "m" (&x));
}
};
This works for me in g++.
You can do
asm(".word x")
(it will work only for file-scope variables symbols as only they potentially get a symbol table entry). It's not constant expression, but the address is anyway not known until the program is fully linked.
In C, you could do this, but, in C, as you are using char *'s as your strings, you need something like this:
printf("%i-%i", &string[0], &string[strlen(string) - 1]);
That prints the range of memory the string is in, istead of the starting adress.
The error output operand constraint lacks = is because haven't operator = before of the operator out m. Take =m
Related
I want to convert a non constant variable to constant variable. I tried using const_cast but still the following program is giving error that ‘bitsize1’ cannot appear in a constant-expression. What am i doing wrong ?
#include <string>
#include <bitset>
#include <iostream>
using namespace std;
int main(){
int l = 3; // taken input from user
int bitsize2 = (l * 2);
int bitsize1 = const_cast<int&>(bitsize2);
string temp = "100101";
bitset<const_cast<int&>(bitsize2)> baz (temp);
cout << baz;
return 0;
}
const_cast is used to cast const away not to make something const. If you want constant expression the easiest way in post-C++11 programming is to use constexpr:
constexpr int l = 3;
constexpr int bitsize2 = l * 2;
The input from user cannot be a compile time constant expression so you must figure out something else.
Templates are expanded in compile time, this means that all template arguments should be known when compiling. Obviously user input is runtime data thus cannot be used as a template argument.
As stated by others, you cannot deduce template parameters at runtime.
You should look into using boost's dynamic bitset.
It exists for the exact problem that you have run into.
"The dynamic_bitset class is nearly identical to the std::bitset class.
The difference is that the size of the dynamic_bitset (the number of
bits) is specified at run-time during the construction of a
dynamic_bitset object, whereas the size of a std::bitset is specified
at compile-time through an integer template parameter."
Suppose I have a function that takes a string as input:
SomeOutputType f_impl(const char* s);
Most call sites just use string literals as input, e.g. f("Hello, world"). Suppose I have implemented the following function to compute the result at compile time
template <char...> SomeOutputType f_impl();
My question is, is there a way to let the call sites like f("Hello, world") calls the templated form, while for general call sites like string s="Hello, world"; f(s.c_str()); calls the general form? For clarification, auto s = "Hello, world"; f(s); don't have to call the templated form because s is now a variable and no longer a compile time constant.
A useful case for this question is to optimize printf. In most cases the format will be string literals so a lot of things can be done at compile time to optimize things, instead of parsing the format at runtime.
No, a string literal like "foo" has the type const char[S + 1] where S is the number of characters you wrote. It behaves like an array of that type with no special rules.
In C++03, there was a special rule that said that a string literal could convert to char*. That allowed you to say
#define isStringLiteral(X) \
isConvertibleToCharStar(X) && hasTypeConstCharArray(X)
For example isStringLiteral(+"foo") would yield false, and isStringLiteral("foo") would yield true. Even this possibiliy would not have allowed you to call a function with a string literal argument and behave differently.
C++11 removed that special conversion rule and string literals behave like any other arrays. In C++11 as a dirty hack you can compose some macros, matching some simple string literals without handling escape sequences
constexpr bool isStringLiteral(const char *x, int n = 0) {
return *x == '"' ?
n == 0 ?
isStringLiteral(x + 1, n + 1)
: !*(x + 1)
: (*x && n != 0 && isStringLiteral(x + 1, n + 1));
}
#define FastFun(X) \
(isStringLiteral(#X) ? fConstExpr(X, sizeof(X) - 1) : f(X))
While I haven't tested this, I think if you just declare the function constexpr and compile with high optimization, the compiler will compute at compile time whenever possible. As a bonus, you don't need to write the code twice. On the other hand, you have to write it once in constexpr style.
If I understand the question correctly, I actually think something like this is possible using a function overload. Here's an article that shows the basic idea. In your case I think it would be sufficient to have the following two overloads:
void f(char const *);
template<unsigned int N>
void f(char const (&)[N]);
The latter should be invoked when the string is a string literal, the latter at other times. If the compiler is sufficiently good at optimizing then calls to the latter may be evaluated at compile time.
EDIT:
Alright, it bothered me that the above solution didn't work, so I did some playing around and I think I came up with a solution:
#include <string>
#include <boost/utility/enable_if.hpp>
template<typename T>
struct is_string_literal {
enum { value = false };
};
template<unsigned int N>
struct is_string_literal<char const (&)[N]> {
enum { value = true };
};
template<typename T>
typename boost::disable_if<is_string_literal<T> >::type
foo(T) {
std::cout << "foo1" << std::endl;
}
template<int N>
void foo(char const (&)[N]) {
std::cout << "foo2" << std::endl;
}
int main( ) {
std::string bar = "blah";
char const str[] = "blah";
foo(str);
foo("blah");
foo(bar.data());
}
The output (on GCC 4.4 with -O3) is:
foo2
foo2
foo1
I admit that I don't completely understand why this works when the previous solution didn't. Maybe there's something about overload resolution that I don't completely understand.
Before i start i will divide the problem into two parties:
PART 1 :
In c++ to get type of data we can use typeid but it's give you the data as const char* ,and i want it to return the type of the data.
Example:
int data = 20 ;
float data2 = 3.14 ;
char *data3 = "hello world" ;
std::cout<< typeid(data).nam() << endl << endl ;
std::cout<< typeid(data2).nam() << endl << endl ;
std::cout<< typeid(data3).nam() << endl << endl ;
Now i have a function that get data from void* , and convert it to another type :
template <typename t >
void print (void *data )
{
boost::any _t = static_cast<t> (data);
cout << boost::any_cast<t> (_t) << endl << endl;
}
Now this works fine if you know your data type:
Example:
void *mydata = alloca(size_object) ;
void some_function_store_int_data_in_voidpointer( &mydata)
print <int> (mydata); // it's ok .
But this is impractical when you have lots of different datatypes, like this:
void somefunction(args &a , void *dest )
{
/*code returnd data */
}
enum args
{
_INT_ ,
_FLOAT_ ,
_CHARPOINTER_ ,
};
vector <void *test> myvector ;
myvector.resize (3) ;
void somefunction(_INT_ , myvector.at(0) ) ; // store int in void*
void somefunction(CHARPOINTER , myvector.at(0) ) ;// store char* in void*
void somefunction(_FLOAT_ , myvector.at(0) ) ;// store float in void*
print <int> (myvector.at(0));
print <char*> (myvector.at(1));
print <float> (myvector.at(2));
1 - If i use something like this
print <typeid(myvector.at(2))> (myvector.at(2));
i get an error because my data is float and I make it const char*
2 - Perhaps I can pass the type of every value if I have few data. This is OK. But what if I have 100 values from different types!
I am looking for something like: typeid but it' return the type not `const char*.
PART 2
because I have avector I will use a for_each algorithm like this:
for_each ( myvector.begin() , myvector.end() , print</*what i should pass her int , float ,char* ...or what , */>);
In the previous code I can pass only one type to the function so the data from the same type will print. Else the data that are not the same type will print, but completely wrong (Strange format).
So if I pass char* the int data will print completely wrong.
How can I do this differently?
How can I do this differently?
If your intention is to use same function for printing different data formats, then you can do it like this:
#include <iostream>
#include <algorithm>
#include <vector>
template <typename T> class Callback{
public:
void operator()(const T& value) const{
std::cout << value << std::endl;
}
};
template <typename T> Callback<typename T::value_type> makeCallback(const T&){
return Callback<T::value_type>();
}
int main(int argc, char** argv){
std::vector<int> ints(20);
std::vector<float> floats(20);
std::fill(ints.begin(), ints.end(), 0);
std::fill(floats.begin(), floats.end(), 0.0f);
std::for_each(ints.begin(), ints.end(), makeCallback(ints));
std::for_each(ints.begin(), ints.end(), makeCallback(floats));
return 0;
}
However, if you want to store several different data types in same std::vector, then you need "variant" types (like boost::variant, QVariant or similar), and there's no way around it.
I am looking for something like: typeid but it' return the type not `const char*.
In C++ "type" exists only at compilation stage, so you cannot return it, because it no longer exists once program has been compiled. There's no "type", so you can't return it.
So to get a "type" from object you need to implement some kind of "variant" type that can hold any object along with its type information, and pass that "variant" type around. One example of such system is QVariant in Qt 4.
AFAIK implementation of variant type goes like this: there is some kind of table for every type variant supports, you register all types variant class must support in that table. Table provides functions for creating type, destroying type, (de)serializing type, and possibly information about amount of memory required by one object of the type. The table can contain optional information you want, and you can convert entire registration procedure into macros+template combo. As you can see, this is not something that is done automatically by compiler, but something that involves plenty of hassle and must be taken care of by programmer. Also, things get much more fun if program must be able to take types developed externally (in plugins, etc).
As a result of language restrictions, the better idea would be to avoid situations when you need to "return type" when possible - variant systems aren't exactly difficult, but they aren't much fun either, due to all necessary sanity checks and conversions. Example problem: if you pass a string in variant type to a function that is supposed to take a float, should this function attempt to convert string to float? If conversion fails, should it crash/throw exception, or assume that variable has default value? If there's default value for failed conversions, what should it be and how should it be passed? And so on. This isn't a rocket science, but it is quite annoying to deal with.
For example, you could get rid of "void*" (if function takes pointer as an argument, then I would assume that poitner can be NULL/0. So "void*" arguments aren't exactly a good idea). arguments in your functions and use templates to make compiler generate code your want for types you actually use in your program. If templates are not an option, then you need some kind of "variant" type (preferably developed by somebody else), ... or you could switch to another language that provides type information you need. You don't have to use C++, any tool that does the job will do. Relying on RTTI also isn't a perfect solution, becuase if you manage to pass a pointer to something that does NOT contain type information, you'll get a non-standard exception (__non_rtti_object).
If you have a limited list of types you want to support, use boost::variant<int, float, const char*, ...> instead of boost::any (or void*). Then you can define a visitor to call the correct instantiation of the print function.
#include <boost/variant.hpp>
#include <boost/foreach.hpp>
#include <vector>
#include <algorithm>
#include <iostream>
template <class T>
void print(T t)
{
std::cout << t << '\n';
}
struct print_visitor: boost::static_visitor<void>
{
template <class T>
void operator()(T t) const { print(t); }
};
int main()
{
typedef boost::variant<int, double, const char*> Variant;
std::vector<Variant> vec;
vec.push_back(13);
vec.push_back(3.14);
vec.push_back("Hello world");
BOOST_FOREACH(const Variant& v, vec) {
boost::apply_visitor(print_visitor(), v);
}
}
With a void* or a boost::any, I don't think you can do better than use a long if-chain to test all supported types.
C++ is a statically typed language, thus types only really exist in a meaningful way at the compile time, not at runtime. At runtime the best C++ can give you is RTTI which provides you with things like dynamic_cast<> and typeid(), which are however limited to giving you information along the inheritance hierarchy only, i.e. if you have
class Base
class DerivedA : public Base
class DerivedB : public Base
and you have a Base* or Base& you can find out if it's a Base, a DerivedA or a DerivedB. However in your case you only have a void*, which is completely outside of any inheritance hierarchy and thus has no type information associated with it. Thus all typeid() will tell you is that you have a void*, it won't tell you whatever type might hide behind it.
Furthermore a construct like:
print <typeid(myvector.at(2))> (myvector.at(2));
wouldn't work in C++ either, as the type for a template also needs to be known at compile time. Here however the type of .at(2) would only be known at runtime.
So to solve your problem you have to do the type handling yourself. Meaning you have to store the type along with the object you want to store, which would look something like this:
struct Value
{
enum { kInt, kString } type;
union {
int vInt;
char* vChar;
} value;
};
[...]
Value v;
v.type = Value::kInt;
v.value.vInt = 5;
switch(v.type)
{
case Value::kInt:
// do int specific stuff
break;
case Value::kString:
// do string specific stuff
break;
}
The boost::variant<> class that visitor mentioned provides basically the above in a nicely packaged way.
Another thing worth to mention is decltype, decltype is new in C++11 standard and allows you to get the actual type of an object and thus you can write code like:
int a;
decltype(a) b;
Where b gets the same type as a, i.e. int. This sounds exactly like what you want, but it is not, decltype() has the same restrictions as before. It can only work when the type is already known at compile time, it can't do anything with types only known at runtime. Thus it will not work in your situation and is only really useful when doing some more complex template programming.
Long story short, use boost::variant<> or write yourself a class that works in a similar way.
PART 1: I'm not quite sure I fully understand your query, but have you looked at the header file <typeinfo>? struct type_info may be what you're looking for.
I'm trying to compile the following piece of code, I get an error on the line which specializes std::vector, it seems the one parameter being passed-in is somehow being assumed to be two parameters. Is it perhaps something to do with angle-brackets?
Is there a special way/mechanism where by such parameters can be correctly passed to the macro?
#include <vector>
template<typename A>
struct AClass {};
#define specialize_AClass(X)\
template<> struct AClass<X> { X a; };
specialize_AClass(int) //ok
specialize_AClass(std::vector<int,std::allocator<int> >) //error
int main()
{
return 0;
}
The error that I get is as follows:
1 Line 55: error: macro "specialize_AClass" passed 2 arguments, but takes just 1
2 Line 15: error: expected constructor, destructor, or type conversion before 'int'
3 compilation terminated due to -Wfatal-errors.
Link: http://codepad.org/qIiKsw4l
template<typename TypeX, typename TypeY>
class Test
{
public:
void fun(TypeX x, TypeY y)
{
std::wcout << _T("Hello") << std::endl;
std::wcout << x << std::endl;
std::wcout << y << std::endl;
}
};
#define COMMOA ,
#define KK(x) x val;
void main()
{
KK(Test<int COMMOA int>);
val.fun(12, 13);
}
I have a new way to solve this trouble. hope it can help you :)
You have two options. One of which was mentioned already: Using __VA_ARGS__. This however has the disadvantage that it doesn't work in strict C++03, but requires a sufficiently C99/C++0x compatible preprocessor.
The other option is to parenthesize the type-name. But unlike another answer claims, it's not as easy as just parenthesizing the type name. Writing a specialization as follows is ill-formed
// error, NOT valid!
template<> struct AClass<(int)> { X a; };
I have worked around this (and boost probably uses the same under the hood) by passing the type name in parentheses, and then building up a function type out of it
template<typename T> struct get_first_param;
template<typename R, typename P1> struct get_first_param<R(P1)> {
typedef P1 type;
};
With that, get_first_param<void(X)>::type denotes the type X. Now you can rewrite your macro to
#define specialize_AClass(X) \
template<> struct AClass<get_first_param<void X>::type> {
get_first_param<void X>::type a;
};
And you just need to pass the type wrapped in parentheses.
There is a couple of issues here.
First of all, macros are extremely dumb, they're complicated, but essentially amounts to a pure text replacement processus.
There are therefore 2 (technical) issues with the code you exposed:
You cannot use a comma in the middle of a macro invocation, it just fails, BOOST_FOREACH is a well-known library and yet the only thing they could do was to told the user that it's arguments should not contain commas, unless they could be wrapped in parenthesis, which is not always the case
Even if the replacement occurred, your code would fail in C++03, because it would create a >> symbol at the end of the template specialization, which would not be parsed correctly.
There are preprocessing / template metaprogramming tricks, however the simpler solution is to use a type without commas:
typedef std::vector<int, std::allocator<int> > FooVector;
specialize_AClass(FooVector)
Finally, there is an aesthetic issue, because of their pervasiveness, macros are best given names that cannot possibly clash with "regular" (types, functions, variables) names. The consensus is usually to use all upper case identifiers, like in:
SPECIALIZE_ACLASS
Note that this cannot begin by an underscore, because the standard restricts the use of identifiers matching _[A-Z].* or [^_]*__.* to the compiler writers for the standard library or whatever they feel like (those are not smileys :p)
Since the preprocessor runs before semantic analysis, the comma in your template parameter is being interpreted as the argument separator for the macro. Instead, you should be able to use variadic macros to do something like this:
#define specialize_AClass(...)\
template<> struct AClass< __VA_ARGS__ > { X a; };
If you are willing to add a little more code before calling your macro, you could always do this as a workaround:
typedef std::vector<int,std::allocator<int> > myTypeDef;
specialize_AClass(myTypeDef) //works
#define EMPTY()
#define DEFER( ... ) __VA_ARGS__ EMPTY()
specialize_AClass( DEFER (std::vector<int,std::allocator<int> >) )
For simple things you can use typedef
#include <vector>
template<typename A>
struct AClass {};
#define specialize_AClass(X)\
template<> struct AClass<X> { X a; };
specialize_AClass(int) //ok
typedef std::vector<int,std::allocator<int>> AllocsVector;
specialize_AClass(AllocsVector) //ok
int main()
{
return 0;
}
There are lots of other problems with your code, but to address the specific question, the preprocessor just treats < and > as less-than and greater-than operators.
That's the extent of its knowledge about C++.
There are some tricks that can be used to allow template expressions to be passed as macro arguments, but the simple and by an extremely large margin best answer for a beginner is:
DON'T DO THAT.
Cheers & hth.,
In C/C++, how do I determine the size of the member variable to a structure without needing to define a dummy variable of that structure type? Here's an example of how to do it wrong, but shows the intent:
typedef struct myStruct {
int x[10];
int y;
} myStruct_t;
const size_t sizeof_MyStruct_x = sizeof(myStruct_t.x); // error
For reference, this should be how to find the size of 'x' if you first define a dummy variable:
myStruct_t dummyStructVar;
const size_t sizeof_MyStruct_x = sizeof(dummyStructVar.x);
However, I'm hoping to avoid having to create a dummy variable just to get the size of 'x'. I think there's a clever way to recast 0 as a myStruct_t to help find the size of member variable 'x', but it's been long enough that I've forgotten the details, and can't seem to get a good Google search on this. Do you know?
Thanks!
In C++ (which is what the tags say), your "dummy variable" code can be replaced with:
sizeof myStruct_t().x;
No myStruct_t object will be created: the compiler only works out the static type of sizeof's operand, it doesn't execute the expression.
This works in C, and in C++ is better because it also works for classes without an accessible no-args constructor:
sizeof ((myStruct_t *)0)->x
I'm using following macro:
#include <iostream>
#define DIM_FIELD(struct_type, field) (sizeof( ((struct_type*)0)->field ))
int main()
{
struct ABC
{
int a;
char b;
double c;
};
std::cout << "ABC::a=" << DIM_FIELD(ABC, a)
<< " ABC::c=" << DIM_FIELD(ABC, c) << std::endl;
return 0;
}
Trick is treating 0 as pointer to your struct. This is resolved at compile time so it safe.
You can easily do
sizeof(myStruct().x)
As sizeof parameter is never executed, you'll not really create that object.
Any of these should work:
sizeof(myStruct_t().x;);
or
myStruct_t *tempPtr = NULL;
sizeof(tempPtr->x)
or
sizeof(((myStruct_t *)NULL)->x);
Because sizeof is evaluated at compile-time, not run-time, you won't have a problem dereferencing a NULL pointer.
In C++11, this can be done with sizeof(myStruct_t::x). C++11 also adds std::declval, which can be used for this (among other things):
#include <utility>
typedef struct myStruct {
int x[10];
int y;
} myStruct_t;
const std::size_t sizeof_MyStruct_x_normal = sizeof(myStruct_t::x);
const std::size_t sizeof_MyStruct_x_declval = sizeof(std::declval<myStruct_t>().x);
From my utility macros header:
#define FIELD_SIZE(type, field) (sizeof(((type *)0)->field))
invoked like so:
FIELD_SIZE(myStruct_t, x);