And*_*Sun 17 c const visual-studio pointer-conversion
我一直认为这const char **x是一个正确的类型,用于动态分配的const字符串数组,如下所示:
#include <stdlib.h>
int main()
{
const char **arr = malloc(10 * sizeof(const char *));
const char *str = "Hello!";
arr[0] = str;
free(arr);
}
Run Code Online (Sandbox Code Playgroud)
但是,在使用VS2017编译此代码时,我会收到此警告free:
warning C4090: 'function': different 'const' qualifiers
Run Code Online (Sandbox Code Playgroud)
我的代码有问题吗?FWIW,当我和GCC一起编译时,即使有了,也没有任何警告-Wall -Wextra -pedantic.
您的代码没有任何问题.这里的规则可以在C标准中找到:
6.3.2.3指针
指向void的指针可以转换为指向任何对象类型的指针.指向任何对象类型的指针可以转换为指向void的指针,然后再返回; 结果应该等于原始指针.对于任何限定符q,指向非q限定类型的指针可以转换为指向该类型的q限定版本的指针; 存储在原始指针和转换指针中的值应相等.
这意味着任何指向对象类型(到变量)的指针都可以转换为void指针,除非指针是限定的(const或volatile).所以这样做很好
void* vp;
char* cp;
vp = cp;
Run Code Online (Sandbox Code Playgroud)
但这样做并不好
void* vp;
const char* cp;
vp = cp; // not an allowed form of pointer conversion
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好.但是当我们混合使用指针指针时,const-ness是一个非常令人困惑的主题.
当我们有一个时const char** arr,我们有一个指向常量char的指针(提示:从右到左读取表达式).或者在C标准的乱码中:指向要键入的限定指针的指针.arr虽然本身不是一个合格的指针!它只指向一个.
free()期望指向void的指针.我们可以传递任何类型的指针,除非我们传递一个合格的指针.const char**不是一个合格的指针,所以我们可以通过它.
指向类型指针的限定指针char* const*.
注意当我们尝试这个时gcc如何抱怨:
char*const* arr = malloc(10 * sizeof(char*const*));
free(arr);
Run Code Online (Sandbox Code Playgroud)
gcc -std=c11 -pedantic-errors -Wall - Wextra:
错误:从指针目标类型传递'free'的参数1丢弃'const'限定符
显然,Visual Studio提供的诊断不正确.或者您将代码编译为C++,它不允许隐式转换void*.