triple fault
triple fault

Reputation: 14108

Casting result of malloc to char (not char*) - why doesn't compiler complain?

tmpString = (char*)malloc((strlen(name) + 1) * sizeof(char));
tmpString = (char )malloc((strlen(name) + 1) * sizeof(char));

What is the difference between these 2 lines?

My understanding is that the second line is wrong but from some reason the compiler says nothing.

Upvotes: 6

Views: 209

Answers (4)

John Bode
John Bode

Reputation: 123448

Assuming tmpString has type char *, then the second line should be a constraint violation, at least under the latest standard:

6.5.16.1 Simple assignment

Constraints

1 One of the following shall hold:112) — the left operand has atomic, qualified, or unqualified arithmetic type, and the right has arithmetic type;

— the left operand has an atomic, qualified, or unqualified version of a structure or union type compatible with the type of the right;

the left operand has atomic, qualified, or unqualified pointer type, and (considering the type the left operand would have after lvalue conversion) both operands are pointers to qualified or unqualified versions of compatible types, and the type pointed to by the left has all the qualifiers of the type pointed to by the right;

the left operand has atomic, qualified, or unqualified pointer type, and (considering the type the left operand would have after lvalue conversion) one operand is a pointer to an object type, and the other is a pointer to a qualified or unqualified version of void, and the type pointed to by the left has all the qualifiers of the type pointed to by the right;

— the left operand is an atomic, qualified, or unqualified pointer, and the right is a null pointer constant; or

— the left operand has type atomic, qualified, or unqualified _Bool, and the right is a pointer.

Or am I missing something?

Upvotes: 0

Timo Geusch
Timo Geusch

Reputation: 24341

The first line casts the (void) pointer that malloc returns into a pointer to char, thus preserving both its pointeredness. All it is telling the compiler is that "the memory at location X should be viewed as a character array".

The second cast turns the pointer returned by malloc into a single character. That's bad for multiple reasons:

  • You lose the pointer as you've just turned the pointer into something completely different
  • You're also losing the majority of the numerical value of the pointer because the size of the character is much less than the size of the pointer (in a lot of cases, the pointer is 32 or 64 bit in size but the character only 8 bit) and the "superfluous" bits get discarded.

I would think that a compiler with the warning level cranked up sufficiently high should warn about the second assignment.

Upvotes: 5

Armen Tsirunyan
Armen Tsirunyan

Reputation: 132994

Yes, the second line has undefined behavior. Since the case is explicit the compiler simply assumes that you know what you're doing. Essentially, the second cast interprets the first byte of the pointer value as a character code. The last sentence is just illustrative - you can't even rely on that exactly that will happen.

Upvotes: 2

Rafe Kettler
Rafe Kettler

Reputation: 76955

The second line is wrong (casting to a char will truncate the pointer to just one byte, making the data tmpString contains an invalid address), but all casts in C are unchecked so you'll never get an error over them.

Upvotes: 2

Related Questions