I am converting C++ code to C code. Here is the code which needs to be converted-
struct new{
enum new_enum:uint8_t {
head = 1,
tail = 2,
data = 3,
};
};
How to convert this? Can someone explain what is uint8_t in enum? Is it assigning all variables to uint8_t?
The code you provide cannot compile in C++, since the struct name is new.
Anyway, you can try to just drop the :uint8_t. This will change the strongly typed enum to a standard C one. If you are lucky everything will work. If in any other point you have an use of head, tail or data, it won't work. You can do this:
enum new_enum {
new_enum_head = 1,
new_enum_tail = 2,
new_enum_data = 3,
};
Ugly, but likely to work. Of course the enum will have to go out of the struct it was defined in. That again can cause a lot of grief, but less likely.
I am converting C++ code to C code.
This this seems like a strange direction to take.
There is no direct conversion here. Typed enums are a c++ feature.
There is a similar question here: How to emulate strongly typed enum in C?
Related
Basic problem
I'm in a tricky situation that requires taking a pointer to a struct mainset and turning this into a pointer to a struct subset, whose fields are a contiguous subset of the fields of mainset, starting from the first. Is such a thing possible, with well-defined behavior? I realize that this is a pretty terrible thing to do, but I have good and frustrating reasons to do it [explained at the bottom for patient readers].
My attempt an an implementation seems to work, on OS X with the clang compiler:
#include <iostream>
struct mainset {
size_t size;
uint32_t reflex_size;
};
struct subset {
size_t size;
};
using namespace std;
int main(int argc, char *argv[]) {
mainset test = {1, 1};
subset* stest = reinterpret_cast<subset*>(&test);
std::cout << stest->size << std::endl;
}
The output is indeed 1, as I expect. However, I wonder: am I just getting lucky with a particular compiler and a simple case (in reality my structs are more complicated), or will this work in general?
Also, a follow-up question: for other annoying reasons, I worry that I might need to make my larger struct
struct mainset {
uint32_t reflex_size;
size_t size;
};
instead, with the extra field coming at the front. Could my implementation be extended to work in this case? I tried replacing &test with &test+sizeof(test.reflex_size) but this didn't work; the output of the cout statement was 0.
Explanation of why I have to do this
My project uses the GSL library for linear algebra. This library makes use of structs of the form
struct gsl_block {
size_t size;
double* data;
}
and similar structs like gsl_vector and gsl_matrix. So, I've used these structs as members of my C++ classes; no problem. A recently demanded feature for my project, however, is to enable reflection to my classes with the Reflex tool, part of the ROOT ecosystem. To enable reflection for a struct like this in Reflex, I must add an annotation like
struct gsl_block {
size_t size;
double* data; //[size]
}
This annotation tells Reflex that that the length of the array is provided by the field size of the same struct. Normally that would be that, but Reflex and ROOT have a very unfortunate limitation: the length field must be 32 bit. Having been informed that this limitation won't be fixed anytime soon, and not having the time/resources to fix it myself, I'm looking for workarounds. My idea is to somehow embed a struct bit-compatible with gsl_block within a larger struct:
struct extended_gsl_block {
size_t size;
double* data; //[reflex_size]
uint32_t reflex_size;
}
and similar things for gsl_vector and gsl_matrix; I can ensure that reflex_size and size are always equal (neither is ever bigger than ~50) and Reflex will be able to parse this header correctly (I hope; if reflex_size is required to precede data as a field something more difficult would be required). Since GSL routines work with pointers to these structs, my idea is this: given a pointer extended_gsl_block*, somehow get a pointer to just the fields size and data and reinterpret_cast this into a gsl_block*.
You are in luck.
The classes you show as an example conform to the requirements of standard layout types.
You can read more here:
http://en.cppreference.com/w/cpp/language/data_members#Standard_layout
You can test this premise in the compiler with:
static_assert(std::is_standard_layout<gsl_block>::value, "not a standard layout");
My intention is to build such a data structure in C++:
struct callbackDataUnit {
std::string columnName;
std::string columnData;
};
std::vector<callbackDataUnit> callbackRow;
std::vector<callbackRow> callbackSet; <--- Invalid... It needs a type here
The compiler first complains about the lack os static on callbackRow. Even if I use static there, it still does not compile as the structure is naturally invalid
I would like to take this opportunity to understand a little more about C++ (I´m a beginner on that area), so here goes my questions:
a) Why do we need the static qualifier here ?
b) How can I solve this matrix of the first variables ? I could create 3 classes here (CallbackDataUnit, CallbackRow and CallbackSet) but I feel I would be missing real C++ power here. Would it make sense to make callbackRow a single element struct, so that it can be added to callbackSet ?
Thanks for helping
I think you want define new types, not variables.
To do that, you can use typedef or using.
typedef std::vector<callbackDataUnit> callbackRow;
typedef std::vector<callbackRow> callbackSet;
using callbackRow = std::vector<callbackDataUnit>;
using callbackSet = std::vector<callbackRow>;
If you want to just define variables, you can use:
std::vector<callbackDataUnit> callbackRow;
std::vector<decltype(callbackRow)> callbackSet;
I would like to know how.
I have looked at this topic, and I understand that "The choice of type is implementation-defined.", but I am curious to know how to get 1 instead of 4.
C++11 introduced a way to change the underlying type of an enum.
enum foo : char { ... };
enum class foo : char { ... };
Still, you're probably better off with using the default int in most cases.
On GCC, you can also use the 'packed' attribute to tell the compiler you care more about space than word alignment / access speed:
enum foo { ... } __attribute__((packed));
There are similar hints for other compilers too.
(This is useful when trying to avoid any C++11 features that aren't yet supported by your compiler or IDE.)
I have an Objective C selector which returns integers. I have a C++ instance method which expects an enum. How can I link them? I'm in an Objective C++ (.mm) class while I'm doing this.
I want to call this:
TKClass::foo(MyEnum enumVal) { ... }
With the return value of this:
- (int) intValue { ... }
Like this:
myCPPInstance->foo([myObjCInstance intValue]);
I've tried casting (foo((MyEnum) [myObjCInstance integerValue])) but it doesn't work. I definitely don't want my Objective C object to know anything about the enum; intValue needs to stay as an integer. Similarly, I don't really want to have the C++ method worry about integer inputs when it should be accepting enums.
I'm not much of a C++ programmer, so sorry if this is easy.
Thanks
EDIT: The enum is defined like this:
enum MyEnum {
Apples = 0,
Bananas = 1,
Chocolate = 2
};
It was a namespace issue. The cast should have been:
myCPPInstance->foo((myNamespace::MyEnum) [myObjCInstance intValue]);
Is it possible to get access to an individual member of a struct or class without knowing the names of its member variables?
I would like to do an "offsetof(struct, tyname)" without having the struct name or member variable name hard coded amoungst other things.
thanks.
Sure. If you have a struct and you know the offset and the type of the member variable, you can access it using pointers.
struct my_struct {
int member1;
char member2;
short member3;
char member4;
}
...
struct my_struct obj;
short member3 = *((short*)((char*)&obj + 5));
That'll get the value of member3, which is 5 bytes on from the start of obj on an x86 computer. However, you want to be careful. First of all, if the struct changes, your data will be garbage. We're casting all over the place, so you get no type safety, and the compiler won't warn you if something's awry. You'll also need to make sure the compiler's not packing the struct to align variables to word boundaries, or the offset will change.
This isn't a pleasant thing to do, and I'd avoid it if I were you, but yes, it can be done.
C and C++ are compiled languages without built-in "reflection" features. This means that regardless of what you do and how you do it, one way or another the path will always start from an explicit hard-coded value, be that a member name or an compile-time offset value. That means that if you want to select a struct member based on some run-time key, you have no other choice but to manually create a mapping of some kind that would map the key value to something that identifies a concrete struct member.
In C++ in order to identify a struct member at run-time you can use such feature as pointers-to-members. In C your only choice is to use an offset value.
Another issue is, of course, specifying the type of the members, if your members can have different types. But you provided no details about that, so I can't say whether you need to deal with it or not.
We had a similar problem some years ago: A huge struct of configuration information that we wanted to reflect on. So we wrote a Perl script to find the struct, parse its members, and output a C++ file that looked like:
struct ConfField
{ const char* name;
int type;
size_t offset;
};
ConfField confFields[] = {
{ "version", eUInt32, 0 },
{ "seqID", eUInt32, 4 },
{ "timestamp", eUInt64, 8 },
// ... lots more ...
{ 0, 0, 0 }
};
And we'd feed the script with the output from gcc -E.
Nowadays, I understand that gccxml can output an XML file representing any C++ source that gcc can compile, since it actually uses the g++ front end to do the parsing. So I'd recommend pairing it with an XML-parsing script (I'd use Python with the lxml library) to find out everything you ever wanted to know about your C++ source.
Somewhere in your code you need to reference the data member in the struct. However you can create a variable that is a pointer to a struct data member and from then on you no longer need to reference it by name.
struct foo
{
int member1;
int member2;
};
typedef int (foo::*intMemberOfFoo);
intMemberOfFoo getMember()
{
if (rand() > RAND_MAX / 2) return &foo::member1;
else return &foo::member2;
}
foo f;
void do_somthing()
{
intMemberOfFoo m = getMember();
f.*m = 0;
}
The technical answer is 'yes' because C++ is Turing-complete and you can do almost anything if you try hard enough. The more practical answer is probably 'no' since there is no safe and easy way of doing exactly what you want.
I agree with GMan. What exactly are you trying to do that makes you think you need this technique?
Well you will have to set up some stuff first, but it can be done. Expanding on Samir's response
struct my_struct {
int member1;
char member2;
short member3;
char member4;
}
you can create a table of offsets:
my_struct tmp;
int my_struct_offsets[4]={
0,
(char*)&(tmp.member2)-(char*)&(tmp.member1),
(char*)&(tmp.member3)-(char*)&(tmp.member1),
(char*)&(tmp.member4)-(char*)&(tmp.member1)
}
this will take into account different alignments on different systems