typecasting "auto" type?

Is there a way to perform a cast without explicitly specifying the type so that it is instead derived from the variable?

1
2
3
4
char* data; data=athing;
int rhubarb;
rhubarb=*reinterpret_cast<int*>(data); 
data+=sizeof(rhubarb);


Say I want to upgrade rhubarb to a long long. I'd have to rewrite every cast where it's used. Can I avoid this without using #define?
Last edited on
Why are you casting in the first place? Casting should be the very last option.

It's more readable than memcpy

ETA: I'm parsing raw data
Last edited on
But it's also much less type safe. If you make a mistake the compiler will probably not catch the problem.

Perhaps you should show a small sample of your program where you think casting is "more readable".

Sure

1
2
3
4
5
6
7
8
9
10
11
12
13
void parsepacket(char* data, unsigned long sz){
	char* odata=data;
	char type[4]; memcpy(type, data, 3); type[3]='\0'; data+=3;
	if(type=="INI"){
		Form1->DTdpts_processed=0;
		Form1->DTiter_current=0;
		Form1->DTiter_max=*reinterpret_cast<unsigned long long*>(data); data+=sizeof(Form1->DTiter_max);
		Form1->DTdpts_total=*reinterpret_cast<unsigned long long*>(data); data+=sizeof(Form1->DTiter_max);
		Form1->DTfeed.resize(*reinterpret_cast<unsigned*>(data)); data+=sizeof(unsigned);
	}
       //....
       delete[] odata;
}
Your really not showing enough content. Without seeing how the class/structure is defined and without seeing how data is populated and defined it is hard to see the purpose of the memcpy() and the actual purpose of the casts.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
template <typename T>
void extract(char*& data, T& t)
{
    t = *reinterpret_cast<T*>(data);
    data += sizeof(t);
}

template <typename T>
T extract(char*& data)
{
    T t = *reinterpret_cast<T*>(data);
    data += sizeof(t);
    return t;
}

void parsepacket(char* data, unsigned long sz) {
    char* odata = data;
    char type[4]; memcpy(type, data, 3); type[3] = '\0'; data += 3;
    if (type == "INI") {
        Form1->DTdpts_processed = 0;
        Form1->DTiter_current = 0;
        extract(data, Form1->DTiter_max);
        extract(data, Form1->DTdpts_total);
        Form1->DTfeed.resize(extract<unsigned>(data));

    }
    //....
    delete [] odata;
}


Perhaps?

[edit: Extract should've been using T* in the casts rather than T.]
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class TForm1 : public TForm{
	__published:	// IDE-managed Components
	//...
	private:
	//...
	public:
	//...
	unsigned long long DTdpts_total;
	unsigned long long DTdpts_processed;
	std::vector<float> DTfeed;
	unsigned char DTiter_current;
	unsigned char DTiter_max;
	__fastcall TForm1(TComponent* Owner);
};

char* data is received from a TCP socket. Application is still a WIP
The memcpy() call is just used because my IDE doesn't support the == operator for std::string and char* and I don't want to pollute all those clean comparisons with a .c_str(). Otherwise I'd just have gone with std::string type(data, data+3);
Thanks cire - works beautifully
I wasn't really looking at this specific line since it isn't directly involved in what you're asking but:

if (type == "INI") {

will always be false. The address of the string literal will never be the address of type.

Since data is already a sequence of char, perhaps you could do something like:

1
2
3
4
5
void parsepacket(char* data, unsigned long sz) {
    char* odata = data;

    char* type = data; data += 3;
    if (0 == strncmp(type, "INI", 3)) {
Right - I'm too used to MSVC std::string comparisons... Thanks again
Topic archived. No new replies allowed.