Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Casting const void pointer to array of const char pointers properly in C

I have a piece of C code that looks like this:

const char (*foo)[2] = bar();

Now bar() is a function that returns a (const void *). How do I properly cast this const pointer? The code produces this warning from GCC :

"initialization discards qualifiers from pointer target type".   

Here are some of my unsuccessful attempts:

const char (*foo)[2] = (const char *)bar();
const char (*foo)[2] = (const void **)bar();

The original code does work, I just can't get rid of the warnings by properly casting the return value.

EDIT : This has been suggested:

const char (*foo)[2] = (const char (*)[2])bar();

It appears to be correct, but GCC gives this warning :

"cast discards qualifiers from pointer target type"   

which is nearly identical to the original warning.

EDIT 2 : OK, I think I've got it. The real problem here is the ( const void * ) definition of bar(). The const in the definition (const char( * )[2]) refers to the elements of the array, not the pointer to the array. This type definition is essentially an array, which when represented by a void pointer is not const. The real answer is that a ( const void * ) loses its const-ness when cast to (const char ( * )[2]).

like image 298
postfuturist Avatar asked Nov 08 '09 11:11

postfuturist


People also ask

What is const void * in C?

const void is a type which you can form a pointer to. It's similar to a normal void pointer, but conversions work differently. For example, a const int* cannot be implicitly converted to a void* , but it can be implicitly converted to a const void* .

Can a void pointer be const?

A void pointer is a special pointer that can point to objects of any given data type. A void pointer can be converted into a pointer of another data type by using either C-style casting or static cast. We can not convert void pointers into constants. The malloc() function is used to allocate memory to a void pointer.

How to print a pointer pointer in C?

Printing pointers. You can print a pointer value using printf with the %p format specifier. To do so, you should convert the pointer to type void * first using a cast (see below for void * pointers), although on machines that don't have different representations for different pointer types, this may not be necessary.


2 Answers

Several others have stated the correct cast, but it generates a spurious warning. That warning comes from a possible bug in the C standard, or (depending on your interpretation) a case that GCC should treat specially. I believe the const qualifier can be safely and unambiguously lifted to the array type. You can drop that warning with -Wno-cast-qual but of course that will eliminate warnings for cases that you actually care about.

To elaborate, the type const char (*)[2] means "pointer to array (length 2) of const char". The array is not marked const, just the elements of the array. When compared to the type const void *, the compiler notices that the latter is a pointer to const, where as the former is not, thus generating the warning. The C standard provides no way to mark an array as const, even though a const array would be equivalent to an array of const.

like image 181
Jed Avatar answered Sep 28 '22 07:09

Jed


Try:

const char (*foo)[2] = (const char (*)[2])bar();

Edit but if bar returns a pointer to a const array of char pointers as your question title hints, there should be no need for a cast if you assign to a variable of this type:

char* const* foo = bar();
like image 31
CB Bailey Avatar answered Sep 28 '22 06:09

CB Bailey