一个有一个成员的结构,有时需要```,有时不需要

sle*_*ske 3 c warnings const

我正在研究一个程序,它struct在许多地方使用泛型来绕过相关的值.该结构包含一个字段char* s.

许多功能修改s; 但是,有时结构用于将信息传递给只读取它的函数.在这些情况下,用于初始化的字符串通常s是a const char*.但是,将其分配会s导致编译器警告.

虽然技术上是正确的,但这个警告感觉不对,因为该功能不会修改s.有没有办法绕过这个警告,除了扔掉const?有没有办法让函数承诺它会将struct成员视为const

例:

#include <stdio.h>

struct mystruct{
  int i;
  char* s;
};

void i_only_read(const struct mystruct *m){
  printf("mystruct: i=%d, s=%s\n", m->i, m->s);
}

int main(int argc, char **argv){
  const char* cstr = "Hello";
  struct mystruct m;
  m.i=99;
  /* gcc warning: assignment discards ‘const’ qualifier
   * from pointer target type
   */
  m.s=cstr;
  i_only_read(&m);
}
Run Code Online (Sandbox Code Playgroud)

笔记

  1. 我无法将结构的声明更改为const char* s,因为大多数指向结构的函数都会修改s.
  2. 我想我可以有两个结构,一个带有char* s一个带const char* s,但是看起来非常难看(创建冗余,需要两个结构之间的转换功能).
  3. 如果有人对程序感兴趣是Navit,那么结构就是struct attr.我为这个问题创建了一个简单的例子.

pad*_*ddy 5

有趣的是,你似乎能够在以下方面做到这一点union:

struct mystruct {
    int i;

    union {
        char *s;
        const char *cs;
    };
};
Run Code Online (Sandbox Code Playgroud)

现在,unionapply 的规则:仅使用分配给的union成员.如果函数'promises'表现出来,您可以在cs不发出警告的情况下将字符串分配给.

具体来说,你应该不会做的是分配给cs,然后通过结构作为一个非const参数.

  • 然而,AFAIK,1.通过联合打字是安全的,并且2.相同类型的合格和非限定版本保证具有相同的表示和对齐要求,因此当`cs'被初始化时读取`s`是安全的.反之亦然. (3认同)
  • 但是,你永远不应该依赖你的"实践"经验.如果某些东西不符合标准,那么它就不会"起作用",它只会**正常工作.** (2认同)
  • C11中允许使用匿名联合元素(而不是C99或C89).第6.7.2.1节8适用于C11:_如果struct-declaration-list不包含任何命名成员,直接或通过匿名结构或匿名联合,则行为未定义._ C99中相应的措辞是:§ 6.7.2.17:_如果struct-declaration-list不包含命名成员,则行为未定义._在C11中,§6.7.2.12和§6.7.2.113进一步描述了匿名结构和联合. (2认同)