过去十年(或更长时间?)关于 C 语言中 char** 和 char*[] 声明的语义的感知变化

问题描述 投票:0回答:1

编译器上下文

首先,我目前正在使用

Microsoft Visual Studio Community 2022 (64-bit) - Current Version 17.7.5
(以防万一这个问题更多的是关于我正在使用的工具而不是语言,当我建议这是关于 c 语言本身时我错了。)

问题基础

下面的情况 1 给出了此错误:

expression must be a modifiable lvalue

/* case 1 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static char* defaultlist[] = { "string 1", "string 2" };
char** getlist() { return NULL; }
int main( int argc, char* argv[] ) {
    char* list[]= getlist();      /* line with declaration I'm accustomed to using in past */
    if ( list == NULL )
        list = defaultlist;       /* line with error message */
    return 0;
}

情况2没问题:

/* case 2 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static char* defaultlist[] = { "string 1", "string 2" };
char** getlist() { return NULL; }
int main( int argc, char* argv[] ) {
    char** list= getlist();       /* modified declaration */
    if ( list == NULL )
        list = defaultlist;       /* no error, anymore */
    return 0;
}

在我古老的过去,“

char** p
”和“
char* p[]
”的声明之间没有任何语义差异。在 1970 年代、1980 年代和 1990 年代,当我花在 c 上的时间比最近多时,它们在所有声明上下文中都具有相同的语义。 (如果我错了,我希望得到严厉的纠正并举一个例子来说明差异。)

我现在观察到来自编译器的抱怨,它提出了我以前不习惯的新语义。看来现在,c编译器已经决定

char* list[]
真的是
char* (* const list)
。这不是我的本意。

问题

应注意以下几点:

  • 我是否错误地断言
    char** p
    char* p[]
    的声明语义在某些时候是相同的?如果是这样,并且如果即使回到 1978 年我第一次学习 C 语言来处理 Unix v6 内核代码时它也一直是不同的,那么它究竟有何不同以及如果我尝试这样做的话我如何检测到差异? (我这里有很多旧的编译器,可以用于测试目的。)
  • 我正确地认识到
    char** p
    char* p[]
    的声明语义现在有所不同,因为
    char* p[]
    在我尚未了解的某些情况下实际上被视为
    char* (* const p)
    并且这c 标准的某些修订发生了变化吗? (或者我错过了考虑的其他语义?)
  • 假设我对标准进行了更改,那么更改是什么时候进行的?
c semantics
1个回答
0
投票

在我古老的过去,两者之间没有任何语义差异 一个声明为 char** p,另一个声明为 char* p[]。他们有 在 20 世纪 70 年代、1980 年代的所有声明上下文中具有相同的语义, 1990 年代我花在 c 上的时间比最近更多

这从来都不是事实。区别从C语言开始都是一样的。

  • char **p;
    声明一个指向 char 的指针。
  • char* defaultlist[] = { "string 1", "string 2" };
    定义了两个指向char的指针的数组。

数组无法赋值(即用作左值),指针可以。

这两行都不会编译:

char* list[]= getlist(); 
list = defaultlist; 

您的困惑是初学者对数组和指针的普遍误解。

当用作右值时,数组会衰减为指针,但它们不是指针。

© www.soinside.com 2019 - 2024. All rights reserved.