【问题标题】:Accessing an array within a struct causes warnings with clang访问结构中的数组会导致警告与 clang
【发布时间】:2021-09-17 14:32:14
【问题描述】:
struct test{
   char c_arr[1];
};

test array[1] = {{1}};

test get(int index){
 return array[index];
}

int main(){
  char* a =  get(0).c_arr;
  return 0;
}

使用g++ 编译没有警告,但使用clang++ 会打印以下内容:

warning: temporary whose address is used as value of local variable 'a' will be destroyed at the end of the full-expression

这是不正确的吗? get(0).c_arr 不返回指向全局数组的指针吗?

还是 get(0) 返回一个临时变量,而编译器错误地认为 c_arr 只是它的一个实例,而不是全局变量?

编辑

为什么将这个临时变量传递给函数没有警告?

void call(char* in){}

int main(){
  call(get(0).c_arr);
  return 0;
}

【问题讨论】:

    标签: c++ temporary-objects


    【解决方案1】:

    get 按值返回,然后get(0) 确实返回一个临时值,该临时值在完整表达式后被销毁,留下a 是一个悬空指针。

    注意返回的临时test是从array[index]复制而来的,包括数组数据成员c_arra 应该指向临时test 的数据成员数组c_arr 的第一个元素,在完整表达式之后(即char* a = get(0).c_arr; 中的;)整个临时test(及其数据成员c_arr) 被销毁,然后a 变得悬空。

    如果get 按引用返回,那就没问题了。

    test& get(int index){
     return array[index];
    }
    

    编辑

    您添加的代码很好。临时在完整表达式之后被销毁,即在call(get(0).c_arr); 中的; 之后。传递给call 的指针在call 内仍然有效。

    【讨论】:

    • 这里的表达式结束意味着get(0).c_arr的结束?但是c_arr 这里返回的是一个全局指针,它仍然有效?
    • @Dan 不,get 返回从array[index] 复制的test,而不是直接全局数组的元素。
    • 我明白了get(0).c_arr 返回一个指向不再存在的数组的指针,而不是全局数组。为什么g++ 不会警告它呢?即使在编译Cclang 也可以吗?如果我可以问,如何在 C 中解决这个问题?
    • 我还在edit下添加了一个额外的问题。
    • 非常感谢您提供的信息。我还可以问你为什么这个在C 中没有警告,是未定义的行为吗?由于引用不存在,什么是解决方法?
    猜你喜欢
    • 1970-01-01
    • 2021-08-14
    • 1970-01-01
    • 2017-05-01
    • 1970-01-01
    • 2011-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多