0

given const pointer to string, how can I send it to function that get non const pointer to string.
For example:
The function - int Func(char* str); , and I want to do it:

const char* s=malloc(3);  
int n=Func(s);

How can I send s to Func (But s must be from type of const char* , and I can't change the function Func) ?

AskMath
  • 415
  • 1
  • 4
  • 11
  • That depends on `Func`. Why does it accept by a non-const pointer? And why must `s` be a `const` pointer if you allocate it locally? – StoryTeller - Unslander Monica Apr 24 '18 at 09:43
  • 2
    Possible duplicate of [C: Illegal conversion between pointer types: pointer to const unsigned char -> pointer to unsigned char](https://stackoverflow.com/questions/21903648/c-illegal-conversion-between-pointer-types-pointer-to-const-unsigned-char-p) – r3mainer Apr 24 '18 at 09:44
  • 3
    Just a note, but `const char *s = malloc(3);` is a very broken pattern; if the pointer is to `const char` right after allocation, that means you can never use the memory you just allocated ... – unwind Apr 24 '18 at 10:01
  • 1
    Perhaps your code is demonstrative only, however, assigning _uninitialised_ dynamically allocated memory to a const pointer makes little sense. You'd need to access the memory though a non-const pointer to circumvent the restriction, in which case there's no benefit in declaring it as const in the first place. – mhawke Apr 24 '18 at 10:05
  • 1
    @unwind and you can't `free()` it either :) –  Apr 24 '18 at 10:06

2 Answers2

4

Formally, you can never do that. The need to convert from a const-qualified pointer to a non-const qualified pointer always means that the program design is bad. Quite possibly the bad design lies in some 3rd party code which doesn't implement const correctness properly.

In your specific case: either you need to modify the data and then you are possibly using the wrong type in the caller code. Or the function does not need to modify the data, in which case the function is badly written without const correctness.

In practice, C allows all manner of crazy casts, as long as you know the actual type of the data. In this case, data returned from malloc has no type and it is read/write. It gets assigned an "effective type" at the first time you access that location.

So if Func might modify the data but the caller will not, it is perfectly safe to write

int n=Func((char*)s);

It's all about what kind of data that is actually stored at the pointed-at location.

machine_1
  • 4,266
  • 2
  • 21
  • 42
Lundin
  • 195,001
  • 40
  • 254
  • 396
  • good thought about `malloc()` and *effective type*, but note there would be no correct way to `free()` this memory -- so `const [type] *foo = malloc()` remains a broken pattern anyways :) (which of course supports your first paragraph!) –  Apr 24 '18 at 10:09
  • “Formally, you can never do that” is false. Converting a pointer to a const-qualified type to a pointer to a compatible non-const type and modifying the pointed-to data is allowed provided the pointed-to data could have been modified originally (e.g., was not defined with const and is not a string literal). Const was added to C late, which forced some compromises with existing language features to be made, and converting const to non-const is needed in some places, such as `strchr`. – Eric Postpischil Apr 24 '18 at 10:21
  • @EricPostpischil Such pointer conversions aren't actually mentioned by the standard at all. Only the other way around (6.3.2.3/2). When the standard doesn't mention something, it is UB. Compatible type 6.2.7 only points at qualifiers 6.7.3, where we can read (10) `"For two qualified types to be compatible, both shall have the identically qualified version of a compatible type;"` Therefore your statement "... to a compatible non-const type" doesn't make sense. – Lundin Apr 24 '18 at 10:50
  • In practice we only have to consider the rules of pointer conversion 6.3.2.3/7 (particularly concerned about alignment) and the rules of pointer aliasing 6.5/7. As long as there's no issues with those two, any pointer type in C can be converted to any other pointer type. – Lundin Apr 24 '18 at 10:54
  • @Lundin: Such pointer conversions are covered by the standard. Per 6.3.2.3 7, a pointer to an object type may be converted to a pointer to a different type, and, when converted back again, the result is equal to the original pointer. Therefore, if you take the address of a non-const object or a pointer from `malloc`, you have a non-const pointer. If it is converted to a const pointer (by which I mean the pointed-to type is const, not the pointer itself), it can be converted back per 6.3.2.3 7, Then you have a non-const pointer which may legally be used to modify the object. – Eric Postpischil Apr 24 '18 at 10:56
  • @Lundin: For “compatible non-const type” in my comment, substitute “non-const type that is compatible with the unqualified version of the const type.” – Eric Postpischil Apr 24 '18 at 10:57
  • @Lundin: C allows pointer conversions generally but not between pointers to objects and pointers to functions. However, it does not define the values that result from these conversions except for the results of round-trip conversions, of conversions to character type, and of conversions that add qualifiers. So there are issues with pointer conversions: The result of converting a pointer to int to pointer to float is not defined by the C standard (except that it can be converted back). However, the result of converting a const pointer back to its original non-const type is defined. – Eric Postpischil Apr 24 '18 at 11:03
2

You can Force-cast it to char*

    func((char *) s);

Maybe you need to compile it with -fpermissive in order to work

Chus
  • 926
  • 8
  • 9