0

I have the following:

#include <iostream>
#include <fstream>
#include <iomanip>
#include <sstream>
#include <string> 

struct headerStruct{
    uint8_t header;
    uint8_t data_1;
    uint8_t data_2;
    uint8_t data_3;
    uint8_t data_4;
} my_header_0;

struct headerStruct2{
    uint8_t data_8;
    uint8_t data_9;
} my_header_1;

int main(void)
{
    std::stringstream ss;
    for(int i=0; i < 2; i++)   
    {
        ss.str("");
        ss << "my_header_" << i;
        std::cout << "size of struct: " << sizeof(ss) << std::endl; // I know this line will be wrong but you get what I want to do, I want the size to output 5 and 2 for this example
    }
}

there will be times that i would want to iterate the number of headers i have, i.e my_header_0, my_header_1, ... my_header_n. Which is why i tried placing it in the stringstream ss so i could just edit the string and call the sizeof function. There will be times that I will have more version of my_header_n, n being any number each with a different size. However, I am not sure on how to implement this already.

The output of the sample code above is:

size of struct: 248
size of struct: 248

I understand that 248 is the size of the ss object itself.

However, I want my output to be

size of struct: 5
size of struct: 2

which is actually the size of the structs listed above.

Is this possible? Or any recommended ways to have the expected output.

Nard
  • 45
  • 1
  • 6
  • You cant place the "struct" as a string anywhere. There is only a string in the stringstream, it has nothing to do with the struct. Try to create an array which you could iterate of your structs and then iterate over them. Remember, C++ is'nt an interpreted language – RoQuOTriX Jul 08 '20 at 05:07
  • 2
    `sizeof(ss)` gives you the size of `ss` (the size of a stringstream). C++ is a statically typed language and does not have the type reflection feature you seem to be looking for. You'll have to do it some other way. – Raymond Chen Jul 08 '20 at 05:10
  • @RoQuOTriX so you mean to say there is no way to get the name of the struct, like place it in a string, and then later on try calling the struct using the struct name? – Nard Jul 08 '20 at 05:13
  • @RaymondChen any suggestions how? I have to iterate over several structs that have similar name, just different number in the names, i.e. the _0, _1, _2, etc. – Nard Jul 08 '20 at 05:14
  • I tried this out since sizeof(my_header_0) or sizeof(my_header_1) works right? It gives out 5.... but if I had a lot of the "my_header_n", let n=1 to 100, is there a way to do this in a for loop or so? – Nard Jul 08 '20 at 05:15
  • 1
    @Nard no there is no way in C or C++ to e.g. create an object based on a name in a string, without hardcoding a translator. – RoQuOTriX Jul 08 '20 at 05:15
  • @Nard, sizeof not returns size of elements, returns size of element in bytes. – GobeRadJem32 Jul 08 '20 at 05:15
  • @Nard but there is a difference between sizeof(my_header_0) and sizeof("my_header_0") – RoQuOTriX Jul 08 '20 at 05:16
  • The size of an object is independent of its value. Changing the value of `ss` does not change its size. Also, the name of an object has no connection to the object at run time, only at compile time. – David Schwartz Jul 08 '20 at 05:16
  • @RoQuOTriX yes i know there is no difference in size, but you know what i mean... like if there was another another defined struct with a different size for each _# – Nard Jul 08 '20 at 05:18
  • @DavidSchwartz understood, but you do understand what I am tying to accomplish right? Is there a way to do this? – Nard Jul 08 '20 at 05:19
  • @Nard I actually don't understand what you're trying to accomplish. You never really stated what your actual issue is. But the probable gist of it is that you need to take the thing you want to iterate and represent it in *data* instead of code. – David Schwartz Jul 08 '20 at 05:20
  • @DavidSchwartz haha I want my output to be size of struct: 5, or whatever the size of the struct is (and yes i know the return number is in bytes) :D – Nard Jul 08 '20 at 05:22
  • @Nard That's your proposed solution to whatever problem you have. But that's not a good solution. If we know what problem you actually had, we could suggest good solutions to it. – David Schwartz Jul 08 '20 at 05:24
  • @DavidSchwartz edited the code to see it more realistically:) – Nard Jul 08 '20 at 05:27
  • Also you cannot rely on the size of your struct because of padding: https://stackoverflow.com/questions/119123/why-isnt-sizeof-for-a-struct-equal-to-the-sum-of-sizeof-of-each-member – RoQuOTriX Jul 08 '20 at 05:31
  • For what purpose do you need the size? It sounds like you try to solve a XY-Problem http://xyproblem.info/ Maybe tell us what you REALLY want to achieve – RoQuOTriX Jul 08 '20 at 05:32
  • You're still doing it. "*there will be times that i would want to iterate the number of headers i have*" That's a proposed solution to some problem that you have. What is that problem? (The solution to your problem might be to represent in data what you are currently representing in code. But it's hard to be sure.) – David Schwartz Jul 08 '20 at 05:37
  • @DavidSchwartz ah right! I did not add the output of that code... let me fix it – Nard Jul 08 '20 at 05:38
  • @Nard the output doesn't matter, we want to know, why you want to know the size of the independent structs? – RoQuOTriX Jul 08 '20 at 05:39
  • @RoQuOTriX oh, it's going to be part of another part of the code. The number of iterations of another part of the code will be dependent on the size of the structs. – Nard Jul 08 '20 at 05:44
  • Yes, me and @DavidSchwartz want to know about this mysterious another part of the code. There seems to be a wrong design, if you need the size of a struct depending on the iteration itself. OOP and inheritance seems to be a solution for this problem, but if we do not know, what you are trying really to do, we cannot help – RoQuOTriX Jul 08 '20 at 05:47
  • Taking a guess too: You have a string that contains a number of datasets (serialized in some way) and you want to deserialize it, but there are different types of datasets each with a different number of entries and you have to figure what datasets the string contains? Something like this maybe? – Lukas-T Jul 08 '20 at 06:03
  • he is trying to do rtti based on string value. that's just not possible like this or any other simple way. – Waqar Jul 08 '20 at 06:33

1 Answers1

2

I'd build a map which contains all the objects with their name you want to check. Then use a preprocessor macro to convert the name into a string.

#include <iostream>
#include <map>
#include <stddef.h>
#include <sstream>
#include <string>

struct headerStruct {
    uint8_t header;
    uint8_t data_1;
    uint8_t data_2;
    uint8_t data_3;
    uint8_t data_4;
} my_header_0;

struct headerStruct2 {
    uint8_t data_8;
    uint8_t data_9;
} my_header_1;

// preprocessor macro to convert something into a string
#define getname(n) #n

// map storing the sizes
std::map<const std::string, size_t> map( {{getname(my_header_0), sizeof(my_header_0)},
                                    {getname(my_header_1), sizeof(my_header_1)}});


int main(int argc, char * argv[]) {

    for(auto n : map) {
        std::cout << n.first << " is of size: " << n.second << std::endl;
    }

    std::stringstream ss;
    for(int i = 0; i < 2; ++i) {
        ss.str("");
        ss << "my_header_" << i;

        // get the size from the map
        std::cout << "size_of_struct \"" << ss.str() << "\": " << map[ss.str()] << std::endl;
    }

    return 0;
}

or use more object orientation and store the objets themselves in the database, give them a size function and here we go...

#include <iostream>
#include <map>
#include <stddef.h>
#include <sstream>
#include <string>

struct base {
    virtual size_t size() { return 0; }
};

struct headerStruct : public base {
    uint8_t header;
    uint8_t data_1;
    uint8_t data_2;
    uint8_t data_3;
    uint8_t data_4;
    virtual size_t size() { return 5; }
} my_header_0;

struct headerStruct2 : public base {
    uint8_t data_8;
    uint8_t data_9;
    virtual size_t size() { return 2; }
} my_header_1;

// preprocessor macro to convert something into a string
#define getname(n) #n

std::map<const std::string, struct base &> map( {{getname(my_header_0), my_header_0},
                                    {getname(my_header_1), my_header_1}});


int main(int argc, char * argv[]) {

    for(auto n : map) {
        std::cout << n.first << " is of size: " << n.second.size() << std::endl;
    }

    return 0;
}
PirklW
  • 484
  • 2
  • 16