GCC compiler and convert const char * to char *

I am trying to create a simulator of the M-SIM architecture, but when I run the make utility, gcc reports this error (this is not even a warning)

note: expected 'char *', but the argument is of type 'const char *'

Since this is considered a mistake. Are there any flags that can get around this check?

+4
source share
4 answers

This is a mistake because passing a const char* argument to a function that takes a char* parameter violates const-correctness; this would allow you to modify the const object, which could surpass the whole const target.

For example, this C program:

 #include <stdio.h> void func(char *s) { puts(s); s[0] = 'J'; } int main(void) { const char message[] = "Hello"; func(message); puts(message); return 0; } 

produces the following compile time diagnostics from gcc:

 cc: In function 'main': cc:10:5: warning: passing argument 1 of 'func' discards qualifiers from pointer target type cc:3:6: note: expected 'char *' but argument is of type 'const char *' 

The final message is marked as a β€œnote” because it refers to the (perfectly legal) declaration of func() , explaining that it is a declaration of the parameter to which the warning applies.

Regarding the C standard, this is a violation of the restrictions, which means that the compiler may treat it as a fatal error. gcc by default simply warns about this and does an implicit conversion from const char* to char* .

When I run the program, the output is:

 Hello Jello 

which shows that although I declared message as const , the function was able to change it.

Since gcc did not see this as a fatal error, there is no need to suppress either diagnostic messages. It is possible that the code will work in any case (say, if the function does not change anything). But there are warnings for some reason, and you or the developers of the M-SIM architecture simulator should probably take a look at this.

(Passing a string literal to func() will not lead to this diagnostic, since C does not treat string literals as const . (This makes an attempt to change the string literal undefined.) This is for historical reasons. -Wwrite-strings has the -Wwrite-strings option, which forces it to process string literals as const , which actually violates the C standard, but can be a useful check.)

As I mentioned in the comment, it would be helpful if you showed us the code that runs the diagnostics.

I even downloaded and built a simulator of the M-SIM architecture myself, but I did not see this specific message.

+8
source

First, in a function call (the function defined with the prototype), the arguments are converted to the parameter type, as if they were assigned.

You can assign a char * value to a const char * object, but you cannot assign a const char * value to a const char * object.

This restriction appears in the restrictions of the assignment operator:

(C99, 6.5.16.1p1) "There must be one of the following: [...] - 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 that is pointed to the right ;

This restriction allows the first assignment, but does not allow the second.

Declaring a pointer of type const char * means that you will not modify the object that the pointer points to. Thus, you can assign the pointer a value of type char * , it just means that the object will not be changed using the const char * pointer.

But declaring a char * pointer means that you can change the object that the pointer points to. It does not make sense to assign it a value of const char * .

Remember that in C, const does not mean constant, but rather read-only. The const qualifier placed in front of pointer types means that you promise not to modify objects through objects of these pointer types.

+4
source

Pointers to const -qualified types are implicitly converted to pointers to non-t20> -qualified types. Explicit casting transformation is required, for example:

 foo((char *)bar) 
+3
source

Take these steps if you have not already done so:

  • Declare a char pointer.
  • If necessary, select the space and copy the contents from the constant string. (e.g. using strdup() )
  • And replace the char constant pointer with the new char pointer.
0
source

Source: https://habr.com/ru/post/1391580/


All Articles