C: warning assignment makes integer from pointer without a cast

In summary: The type "array of char" or "array of wchar_t" would be the same regardless of where the string literal was stored (ROM, RAM, code section of a program, ... ).In summary, the conversation is discussing the issue of assigning a string literal to a character pointer in C and the potential issues that may arise from this. It is recommended to use const char* or char const* to declare the pointer and avoid any potential undefined behavior.
  • #1
eatsleep
42
0
C: "warning assignment makes integer from pointer without a cast"

1. I am trying to assign a color to the variable choice if it is equal to one of the 3 input numbers.

Code:
if(pred==1) {
		choice = "RED";
		}
	else if(pred==2) {
        	choice = "GREEN";
		}
	else if(pred==3) {
        	choice = "BLUE";
           	}
I have already initilized choice as a character variable and pred as an integer variable. I am not sure what I am missing but I keep getting the error "warning assignment makes integer from pointer without a cast".
 
Last edited by a moderator:
Physics news on Phys.org
  • #2
"RED" is not a character variable - it is a string. The pointer conversion is from the string pointer.
 
  • #3
choice should be defined as:

char *choice;

if you used "char choice;" then C thinks of char as an 8-bit integer.
 
  • #4
jedishrfu said:
choice should be defined as:

char *choice;
That should be const char* choice, not just char* choice.

Assigning to a pointer to a string such as "RED" is illegal (undefined behavior), so it's best to make the pointer a type that does not accept assignments.
 
  • #5
D H said:
That should be const char* choice, not just char* choice.

Assigning to a pointer to a string such as "RED" is illegal (undefined behavior), so it's best to make the pointer a type that does not accept assignments.

Doesn't this depend on what he's trying to do?

Suppose this choice is in some sort of input loop where first its RED and then its BLUE ...
 
  • #6
jedishrfu said:
Doesn't this depend on what he's trying to do?

Suppose this choice is in some sort of input loop where first its RED and then its BLUE ...

The 'const char* choice' also tells the compiler that the 'data' at locations RED, BLUE, etc ... pointed to by 'choice' will not change so it can possibility optimize operations or memory storage using those locations.

EDIT: Looking at the C/C++ styles just to double check myself:
const char* == char const *
 
Last edited:
  • #7
jedishrfu said:
Doesn't this depend on what he's trying to do?

Suppose this choice is in some sort of input loop where first its RED and then its BLUE ...
There's nothing wrong with that. const char * choice (or char const * choice, same thing) means that choice can be used on the left hand side of an assignment statement but that choice[1] cannot.

You are apparently thinking of char * const choice = "RED";, but that's a completely different data type. With this declaration, choice can only be assigned a value in the declaration statement. However, choice[1]='D'; is perfectly legal with this declaration. You can combine the two restrictions with the declaration const char * const choice = "RED";
 
  • #8
D H said:
Assigning to a pointer to a string such as "RED" is illegal (undefined behavior), so it's best to make the pointer a type that does not accept assignments.
It's my understanding that literal strings are like statics, and exist from start to termination of a program, so why should assigning a pointer to a literal string be undefined? Trying to change a value in the literal string via the pointer would be illegal / undefined behavior, but the pointer assignment shouldn't be an issue.
 
  • #9
D H said:
There's nothing wrong with that. const char * choice (or char const * choice, same thing) means that choice can be used on the left hand side of an assignment statement but that choice[1] cannot.

You are apparently thinking of char * const choice = "RED";, but that's a completely different data type. With this declaration, choice can only be assigned a value in the declaration statement. However, choice[1]='D'; is perfectly legal with this declaration. You can combine the two restrictions with the declaration const char * const choice = "RED";

Thanks for the explanation, but I was referring to char * as the simplest solution to the OP question.

char *choice = "RED";

He can use choice for whatever he wants.
 
  • #10
rcgldr said:
It's my understanding that literal strings are like statics, and exist from start to termination of a program, so why should assigning a pointer to a literal string be undefined? Trying to change a value in the literal string via the pointer would be illegal / undefined behavior, but the pointer assignment shouldn't be an issue.

It depends on the computer architecture and how strict the compiler is. With something like a uC with (modified) 'Harvard' architecture pointers to program literal strings that might be in ROM or flash and pointers to data in ram might require different memory access methods or pointer sizes, so a ram pointer assignment might be illegal or at least a warning.
 
  • #11
rcgldr said:
It's my understanding that literal strings are like statics, and exist from start to termination of a program, so why should assigning a pointer to a literal string be undefined? Trying to change a value in the literal string via the pointer would be illegal / undefined behavior, but the pointer assignment shouldn't be an issue.

nsaspook said:
It depends on the computer architecture and how strict the compiler is.
The point I was making is how string literals are defined in the C89 and later standards. From the C89 standard, section 3.1.4:

A character string literal has static storage duration and type "array of char", and is initialized with the given characters. A wide string literal has static storage duration and type "array of wchar_t", and is initialized with the wide characters corresponding to the given multibyte characters. ...

Identical string literals of either form need not be distinct. If the program attempts to modify a string literal of either form, the behavior is undefined.


So it would seem that only an attempt to modify a string is undefined, not the usage of a pointer to access a literal string. The type "array of char" or "array of wchar_t" would be the same regardless of where the string literal was stored (ROM, RAM, code section of a program, ... ).
 
  • #12
rcgldr said:
The point I was making is how string literals are defined in the C89 and later standards. From the C89 standard, section 3.1.4:
...
So it would seem that only an attempt to modify a string is undefined, not the usage of a pointer to access a literal string. The type "array of char" or "array of wchar_t" would be the same regardless of where the string literal was stored (ROM, RAM, code section of a program, ... ).

In general I agree on Von Neumann/Princeton architecture, C89 compliance pulls a little slight of hand here by hiding the details using "fat pointers" aka "generic pointers" on Harvard architecture but there are still many C compilers for embedded systems that are not strict C89 on this point (The Microchip C18 compiler is an example) for efficiency on small systems.
http://stackoverflow.com/questions/13484050/pointer-for-rom-variable-in-a-ram-variable
 
Last edited:
  • #13
rcgldr said:
It's my understanding that literal strings are like statics, and exist from start to termination of a program, so why should assigning a pointer to a literal string be undefined? Trying to change a value in the literal string via the pointer would be illegal / undefined behavior, but the pointer assignment shouldn't be an issue.
I wasn't clear with my previous post.

There's nothing wrong per se with char* ptr; ...; ptr="RED"; ...; ptr="BLUE"; What's wrong is assigning into that pointer: *ptr = 'A';. What's worse is that most compilers won't report this as an error. You don't find out until runtime.

Declaring the variable as a const char* pointer (or char const*, same thing) and assignments such as ptr="RED"; are still legal, but now *ptr = 'A'; becomes a compile-time error.
 
  • #14
D H said:
I wasn't clear with my previous post.

There's nothing wrong per se with char* ptr; ...; ptr="RED"; ...; ptr="BLUE"; What's wrong is assigning into that pointer: *ptr = 'A';. What's worse is that most compilers won't report this as an error. You don't find out until runtime.

Declaring the variable as a const char* pointer (or char const*, same thing) and assignments such as ptr="RED"; are still legal, but now *ptr = 'A'; becomes a compile-time error.

I agree. I was assuming the OP had enough knowledge not to shoot himself in the foot with C. I used to teach C to others in my company as part of inhouse training and that assumption wasn't always true.
 

FAQ: C: warning assignment makes integer from pointer without a cast

What does the warning "assignment makes integer from pointer without a cast" mean?

This warning indicates that a pointer value is being assigned to an integer variable without being explicitly converted or casted. This can create unexpected behavior and should be avoided.

2. Why does this warning occur in C?

In C, pointers are used to store memory addresses of variables or data. Assigning a pointer value to an integer variable can result in loss of information or incorrect memory access, which is why the compiler issues this warning.

3. How can I fix this warning?

To fix this warning, you can use a typecast to explicitly convert the pointer value to an integer before assigning it to the variable. However, make sure that the conversion is appropriate and does not cause any loss of information.

4. Can this warning cause errors in my program?

While this warning may not always result in errors, it can lead to unexpected behavior and should be addressed. Ignoring this warning can potentially cause issues in your program, so it is best to fix it.

5. Are there any alternatives to using typecasts to fix this warning?

In some cases, using a different data type for the variable may be a better solution than using a typecast. For example, if the pointer is pointing to a string, you can use a string data type instead of converting it to an integer.

Similar threads

Back
Top