Calculate member offset of unknown type - c++

I want to get the offset of a struct's member. I know this has been asked multiple times and the answer is always the mighty offsetof. Well, my case is a little different: I need the offset of an unknown type. That is for example:
void fill_struct(void* unknown)
{
...
}
The only thing I will know from unknown is the order in which types are set. i.e.
int
int
float
...
string
And the main problem here is align/padding, since I don't know a way to calculate it nor if there is a way at all.
This kind of question is often replied with: why would you want to do that?
For those people: I'm implementing a JSON parser in C++, and faced a problem (representing multiple type arrays), and my solution is to map the array's values into a custom struct.
I accept feedback regarding to that solution but I'm mainly interested in my question being answered

Related

Validate function parameters based on given constraints

Before saying anything, please let me make it clear that this question is NOT language-specific but part of my work on an interpreter.
Let's say we have an enum of Value types. So a value can be:
SV, // stringValue
IV, // integerValue
AV, // arrayValue
etc, etc
then let's say we have a function F which takes one of the following combinations of arguments:
[
[SV],
[SV,IV],
[AV]
]
Now, the function is called, we calculate the values passed, and get their types. Let's say we get [XV,YV].
The question is:
What is the most efficient way to check if the passed values are allowed?
(The original interpreter is written in Nim, so one could say we could lookup the value array in the array of accepted value arrays like: accepted.contains(passed) - but this is not efficient)
P.S. ^ That's how I'm currently doing it, although I've explored the option of using bitmasks too. However, I cannot seem how it would help, since order plays an important part too.

Expression must have a constant value error in an array with the size input by user [duplicate]

This question already has an answer here:
Passing an int to a function, then using that int to create an array
(1 answer)
Closed 4 years ago.
So i have this code, part of a larger function.
int size, j;
cout << "Enter the size of array" << endl;
cin >> size;
float b, n[size];// error
and I get the already famous E0028-expression must have a constant value. Now I saw people getting around this with "new int" and while I kinda understand the concept of it, technically I have not learned this type of int, not yet,nor objects etc. Also where I'm learning c++ they tell me that this should work just fine. I use visual studio enterprise 2017 to code(maybe there is a problem on my end with the compiler). Basically what I want is an array that has the size of it decided by the user input. And yes I know it wants to have a const and not a variable value. What are any work-arounds this ? (answer like you would try to teach your dog programming please because that is where my knowledge lies). Thank you.
Edit: While I see people trying to tell me use std::vector(that again i technically did not learn but kinda understand the concept of it) the people from the place where i'm learning c++ are telling me it should work that way.I did read a bit about the error before asking the question and saw some related stuff about the c99 standard( 2 much stuff to make a wall of text here). So the follow up question is: are they teaching outdated ways of writing this stuff ?
Thank you.
Variable length arrays, such as n[size], are not supported by standard C++, although some compilers allow it as an extension. (Note that C allows it, although it was made optional in C11.)
Use std::vector<float> n(size); in your case instead. That will allow you to access elements of n using []; e.g. n[0] is the first element.
As a rule of thumb, use a std::vector to model an array of a numeric type, unless you can think of a good reason not to.
The error is selfeplanatory: you cannnot use non-const expression in float n[size];.
In your case you need to use new operator or use one of standard containers: std::array or std::vector if you want to change the array size later on.

C++ Running Code from file

This might seem a bit far fetched and possible off-topic (sorry if it is), but I'd like to know for sure if it is possible or not.
I am working on a Q and A program.
The text file is laid out in a Question tab Answer newline style.
My question is this: Is it possible to read an answer as a function.
Example:
Question - What time is it? / Answer - getCurrentTime()
Question - What is today's date? / Answer - getCurrentDate()
Then the program, though string parsing, knows that this is a function without an argument and calls the function getCurrentTime() or getCurrentDate() which prints the time or date respectively.
This is possible using an array of function pointers. You just load all the functions into the array. How you obtain the correct index is up to you. The only useful way I can come up with is maintain a second array containing the function names in the same positions as the functions in the function array. Then search the function name array and use the index in that array to access the correct function in the function array. If you need a better explanation leave a message. It is very late at night here and I need to work in the morning.
Barmar's solution will work to and is the better way to go about it but use function pointers.
Hope this helps
dannyhut

How to print elements from tcl_obj in gdb?

I am debugging a c++-tcl interface application and I need to see the elements of Tcl_Obj objv.
I tried doing print *(objv[1]) and so on but it doesnt seem helping.
Is there any way to see Tcl_Obj elements in gdb?
It's not particularly easy to understand a Tcl_Obj * from GDB as the data structure uses polymorphic pointers with shrouded types. (Yeah, this is tricky C magic.) However, there are definitely some things you can try. (I'll pretend that the pointer is called objPtr below, and that it is of type Tcl_Obj *.)
Firstly, check out what the objPtr->typePtr points to, if anything. A NULL objPtr->typePtr means that the object just has something in the objPtr->bytes field, which is a UTF-8 string containing objPtr->length bytes with a \0 at objPtr->bytes[objPtr->length]. A Tcl_Obj * should never have both its objPtr->bytes and objPtr->typePtr being NULL at the same time.
If the objPtr->typePtr is not NULL, it points to a static constant structure that defines the basic polymorphic type operations on the Tcl_Obj * (think of it as being like a vtable). Of initial interest to you is going to be the name field though; that's a human-readable const char * string, and it will probably help you a lot. The other things in that structure include a definition of how to duplicate the object and how to serialize the object. (The objPtr->bytes field really holds the serialization.)
The objPtr->typePtr defines the interpretation of the objPtr->internalRep, which is a C union that is big enough to hold two generic pointers (and a few other things besides, like a long and double; you'll also see a Tcl_WideInt, which is probably a long long but that depends on the compiler). How this happens is up to the implementation of the type so it's difficult to be all-encompassing here, but it's basically the case that small integers have the objPtr->internalRep.longValue field as meaningful, floating point numbers have the objPtr->internalRep.doubleValue as meaningful, and more complex types hang a structure off the side.
With a list, the structure actually hangs off the objPtr->internalRep.twoPtrValue.ptr1 and is really a struct List (which is declared in tclInt.h and is not part of Tcl's public API). The struct List in turn has a variable-length array in it, the elements field; don't modify inside there or you'll break things. Dictionaries are similar, but use a struct Dict instead (which contains a variation on the theme of hash tables) and which is declared just inside tclDictObj.c; even the rest of Tcl's implementation can't see how they work internally. That's deliberate.
If you want to debug into a Tcl_Obj *, you'll have to proceed carefully, look at the typePtr, apply relevant casts where necessary, and make sure you're using a debug build of Tcl with all the symbol and type information preserved.
There's nothing about this that makes debugging a whole array of values particularly easy. The simplest approach is to print the string view of the object, like this:
print Tcl_GetString(objv[1])
Be aware that this does potentially trigger the serialization of the object (including memory allocation) so it's definitely not perfect. It is, however, really easy to do. (Tcl_GetString generates the serialization if necessary — storing it in the objPtr->bytes field of course — and returns a pointer to it. This means that the value returned is definitely UTF-8. Well, Tcl's internal variation on UTF-8 that's slightly denormalized in a couple of places that probably don't matter to you right now.)
Note that you can read some of this information from scripts in Tcl 8.6 (the current recommended release) with the ::tcl::unsupported::representation command. As you can guess from the name, it's not supported (because it violates a good number of Tcl's basic semantic model rules) but it can help with debugging before you break out the big guns of attaching gdb.

What type of input check can be performed against binary data in C++?

let's say I have a function like this in C++, which I wish to publish to third parties. I want to make it so that the user will know what happened, should he/she feeds invalid data in and the library crashes.
Let's say that, if it helps, I can change the interface as well.
int doStuff(unsigned char *in_someData, int in_data_length);
Apart from application specific input validation (e.g. see if the binary begins with a known identifier etc.), what can be done? E.g. can I let the user know, if he/she passes in in_someData that has only 1 byte of data but passes in 512 as in_data_length?
Note: I already asked a similar question here, but let me ask from another angle..
It cannot be checked whether the parameter in_data_length passed to the function has the correct value. If this were possible, the parameter would be redundant and thus needless.
But a vector from the standard template library solves this:
int doStuff(const std::vector<unsigned char>& in_someData);
So, there is no possibility of a "NULL buffer" or an invalid data length parameter.
If you would know how many bytes passed by in_someData why would you need in_data_length at all?
Actually, you can only check in_someData for NULL and in_data_length for positive value. Then return some error code if needed. If a user passed some garbage to your function, this problem is obviously not yours.
In C++, the magic word you're looking for is "exception". That gives you a method to tell the caller something went wrong. You'll end up with code something like
int
doStuff(unsigned char * inSomeData, int inDataLength) throws Exception {
// do a test
if(inDataLength == 0)
throw new Exception("Length can't be 0");
// only gets here if it passed the test
// do other good stuff
return theResult;
}
Now, there's another problem with your specific example, because there's no universal way in C or C++ to tell how long an array of primitives really is. It's all just bits, with inSomeData being the address of the first bits. Strings are a special case, because there's a general convention that a zero byte ends a string, but you can't depend on that for binary data -- a zero byte is just a zero byte.
Update
This has currently picked up some downvotes, apparently by people misled by the comment that exception specifications had been deprecated. As I noted in a comment below, this isn't actually true -- while the specification will be deprecated in C++11, it's still part of the language now, so unless questioner is a time traveler writing in 2014, the throws clause is still the correct way to write it in C++.
Also note that the original questioner says "I want to make it so that the user will know what happened, should he/she feeds [sic] invalid data in and the library crashes." Thus the question is not just what can I do to validate the input data (answer: not much unless you know more about the inputs than was stated), but then how do I tell the caller they screwed up? And the answer to that is "use the exception mechanism" which has certainly not been deprecated.