【问题标题】:why is not possible to have static members in struct?为什么结构中不可能有静态成员?
【发布时间】:2020-05-27 15:08:24
【问题描述】:

首先,从这里开始:

static struct foo1 { //private struct, just for this file
    int a;
};

int main (void) {
    struct foo1 a = {10};
    return 0;
}

问题编号 1

我会收到警告:

warning: useless storage class specifier in empty declaration
 };

这是什么意思?为什么static“无用的存储类说明符”?在其他情况下(函数中的静态局部变量或全局静态,我想申请结构foo1,它会起作用)。

第二个问题

#include <stdbool.h>
static struct s_t{ //private struct (for this file only) 
    static bool is_there = false; // defaul (pre-defined) value for all instances
    int value;
};

int main (void) {}

为什么不能在 c 中为所有 struct s_t 类型的变量提供静态的预定义值?我只是想模拟与函数 static local var 中相同的功能 -> preserve 跨多个调用的值,从这个意义上说,我希望有一个成员(在这种情况下为bool is_therepreserve 值跨越struct foo1 类型的每个变量(它的实例)。那么为什么不可能呢?

问题编号 3

另外,有人可以从中解释错误(更一般意义上):

error: expected specifier-qualifier-list before ‘static’

编辑: 从cmets,我不太了解存储类的概念,我只从asm知道,有data/text/bss segments,那么是不是说static varread-only部分内存中有地址?或者c中storage class与asm相关的概念是什么?

【问题讨论】:

  • 当您通过malloc 为该实例分配内存时,在结构中拥有static 成员的预期结果是什么?为不同的成员设置不同的存储类别会产生什么影响?还是在成员和结构本身之间?结构只是某些数据对象的蓝图。它没有具体说明这将在哪里结束。您似乎混淆了 C 中的静态对象和 C++ 中的静态类
  • @Gerhardh 我知道这只是“蓝图”,但我怎样才能拥有一个成员pre-defined?我只是不想为该类型的每个 var 初始化相同的值,因为它可以拥有所有这些值。我认为这就是 static 的用途
  • @Gerhardh 我没有将C++ 与纯C 混合,我的意思是struct s_t 类型的变量(不是类的实例)我只是简写为instance,但这个问题只针对C lang。
  • C 中不存在静态成员。预定义值也是如此。
  • 蓝图定义了布局。它不会带来所有的家具。

标签: c struct static


【解决方案1】:

因为 struct 就像一个类型或一个对象,当你在 C 中声明一个静态成员时,它会是这样的:

static int a = 0;

在这种情况下,“int”就像你声明的结构类型,所以如果你想创建一个结构静态成员,只需这样做:

static s_t a;

【讨论】:

    【解决方案2】:
    1. 因为static struct foo1 { ... 只是一个结构定义,而不是一个变量。您应该在声明结构实例时添加static。我更喜欢这种风格:

      typedef struct  { 
          int a;
      }foo_t;
      
      static foo_t a = {10};
      
    2. 因为 C 根本没有像 C++ 那样的静态成员变量。在 C 中,将存储或类型说明符添加到单个结构成员是非常无用的。而是将其放在分配的变量上。

    3. TL;DR 这对你的语法没有任何意义,因为你不能在那里拥有static。除非您对语言语法非常感兴趣,否则别无其他。

      static存储类说明符const 等是类型限定符int 等是类型说明符 . specifier-qualifier list 一词来自结构的正式 C 语法,除非您正在制作编译器,否则阅读它并不是很有趣。声明结构成员时,您有两种选择(C17 6.7.2.1):

      specifier-qualifier-list:
         type-specifier specifier-qualifier-list(opt)
         type-qualifier specifier-qualifier-list(opt)
      

      static 不符合两者的要求,因为它是一个存储类说明符,所以编译器说“什么!这不是一个说明符限定符列表,我希望在其中找到一个,它在哪里?”

      (是的,它是递归的,因此您可以拥有多个类型说明符或类型限定符,例如 const long const const int value;。因为 C 代表疯狂。)

    【讨论】:

    • 与@Gerhardh 的 cmets 相同。如果 C 在 struct 中没有静态成员,那么我如何才能使一个成员具有该类型的所有其他初始化变量的值?我只想实现,所有struct s_t 类型的变量都已经定义了成员bool is_therefalse。这就是我认为static 关键字的用途。另外,您能否解释一下您提到的与 asm 段有关的storage classes? (正如我在编辑中要求的那样)
    • @autistic456 不,static 表示变量具有“内部链接”(不能从其他文件访问)和静态存储持续时间(意味着它将最终分配在 .data 或 . bss)。如果你想要只读,你应该使用constis 允许放置在结构成员之前,尽管从程序设计的角度来看,我不会真正推荐它。
    • @autistic456 如果您从汇编程序转向 C,您可能会发现这很有帮助:electronics.stackexchange.com/a/237759/6102。它是在考虑微控制器的情况下编写的,但它几乎是通用的,至少对于“类似 ELF”的二进制文件而言。
    【解决方案3】:
    static struct foo1 { //private struct, just for this file
            int a;
        };
    

    static 声明说明符仅适用于对象或函数声明,不适用于类型定义。您在该语句中所做的只是创建 struct foo1 类型。你有没有写过类似的东西

    static struct foo1 {
      int a;
    } foo;
    

    那么对象 foo 将被声明为static

    如果您在 .c 文件中声明该类型,则它将仅在该 .c 文件中可见。使该类型对多个 .c 文件可见的唯一方法是在标题中声明它,并在每个需要它的文件中声明 #include 该标题。

    为什么不能在 c 中为 struct s_t 类型的所有变量提供静态的预定义值?

    因为 C struct 类型并没有那么复杂——它们只是定义具有多个属性的数据项的一种方式。该语言没有提供任何方法来拥有在该类型的所有实例中通用的成员。

    请记住,C 是 1970 年代初期的产品,最初是为实现 Unix 操作系统而开发的 - 它被设计为小巧、便携和快速。在过去的 40 多年里,它已经添加了很多东西,但并没有真正改变这门语言的核心理念。

    【讨论】:

      【解决方案4】:

      嗯,很明显你会收到警告。原因很简单! 您正在尝试将存储类分配给struct 定义。 但是,存储类适用于变量声明。因此,您得到了提示。 如果您仍然希望使用static 存储类,那么您可以使用任何变量,最好是结构的任何实例。

      【讨论】:

        猜你喜欢
        • 2023-03-06
        • 1970-01-01
        • 2013-02-05
        • 1970-01-01
        • 2013-11-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多