【问题标题】:How to hold a const value in a struct in C (not C++)?如何在 C(不是 C++)中的结构中保存 const 值?
【发布时间】:2014-03-04 06:42:00
【问题描述】:

如何在结构中保存一个常量值?如果我将 const 放在 LEBEL0 上,我将无法在 LEBEL1 上分配给它。但是,如果我不在 LEBEL0 处放置 const,那么我将在 LEBEL1 处收到限定符丢失警告。有没有办法做到这一点?我想出了一个肮脏的解决方案(如下),但我认为可能会有更好的解决方案......

    typedef struct _MyStruct
    {
        const SomePointerType pktData; <--LABEL0
    }MyStruct;

    const SomePointerType SomeFunctionICannotModify()
    {
    …
    }

    void SomeFunction()
    {
       MyStruct data;
    ….
       data.pktData = SomeFunctionICannotModify(); <--LABEL1
   ....
       SomeSubFunction(&data);
    }

    void SomeSubFunction(MyStruct* data)
    {
        this function does not modify any fields in "data".
    }

PS:上面的代码是“模型”,不是真实的代码,用来说明我的问题。它没有我实际程序中的所有代码。请不要问“你为什么要那样做”、“你不必那样做”、“那段代码无法编译”之类的问题。

我的肮脏解决方案

    typedef struct _ConstHolder
    {
        const SomePointerType pktData;
    }ConstHolder;

    typedef struct _MyStruct
    {
        ConstHolder holder;
    }MyStruct;

    void SomeFunction()
    {
       MyStruct data;
    ….
       ConstHolder holder = {SomeFunctionICannotModify()};
       data.holder = holder;
   ....
       SomeSubFunction(&data);
    }

【问题讨论】:

  • 为什么一定要const?
  • 与其制作一些假代码来“说明您的问题”,不如制作一个实际的简短可编译示例?它会同样简单,而且不会那么难以理解。

标签: c struct constants variable-assignment compound-assignment


【解决方案1】:

您的问题很难理解,但您可能会误解为分配给它后无法修改 pktData。这不是真的。考虑以下,这是完全合法的:

const char * str = "hello";
printf("%s\n", str);
str = "goodbye";
printf("%s\n", str);

const 并不是说​​你不能重新分配指针,而是说你不能改变它指向的数据。

【讨论】:

    【解决方案2】:

    在我看来,问题在于您将 typedef 与 const 一起使用。关于 C 的事情是 const 的实现和可用性不如 C++。而且 typedef 也做得不好。

    This article talks a bit about const in Cthis article as well on const in C 也是如此。

    例如,如果您使用以下代码,它将在 Visual Studio 2005 中顺利编译

    typedef char * pchar;
    
    typedef struct {
        int i;
        int j;
    } Thing;
    
    typedef Thing * SomePtr;
    
    typedef struct {
    //  const SomePtr pSome;
    //  const pchar   mychar;
        const char * mychar;
        const Thing *pSome;
    } MyStruct;
    
    const SomePtr SomePtrFunc ()
    {
        static Thing jj = {1, 2};
    
        return &jj;
    }
    
    int main(int argc, char **argv)
    {
        MyStruct josey;
    
        josey.pSome = SomePtrFunc();
    
        josey.mychar = "this";
        return 0;
    }
    

    如果我要尝试修改josey.pSome 所指向的内容,方法是添加一行代码,例如josey.pSome-&gt;i = 0;,那么我将看到一个编译错误error C2166: l-value指定 const 对象

    但是,如果您在 cmets 切换的情况下使用以下代码,则会收到错误消息 error C2166: l-value specified const object

    typedef char * pchar;
    
    typedef struct {
        int i;
        int j;
    } Thing;
    
    typedef Thing * SomePtr;
    
    typedef struct {
        const SomePtr pSome;
        const pchar   mychar;
    //  const char * mychar;
    //  const Thing *pSome;
    } MyStruct;
    
    const SomePtr SomePtrFunc ()
    {
        static Thing jj = {1, 2};
    
        return &jj;
    }
    
    int main(int argc, char **argv)
    {
        MyStruct josey;
    
        josey.pSome = SomePtrFunc();  // <- error C2166: l-value specifies const object
    
        josey.mychar = "this";        // <- error C2166: l-value specifies const object
        return 0;
    }
    

    最后,你可以做的是让 typedef 包含 const 限定符,这将使 const 限定符成为类型的一部分:

    typedef const char * pchar;
    
    typedef struct {
        int i;
        int j;
    } Thing;
    
    typedef const Thing * SomePtr;
    
    typedef struct {
        SomePtr pSome;
        pchar   mychar;
    //  const char * mychar;
    //  const Thing *pSome;
    } MyStruct;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-07
      • 1970-01-01
      • 1970-01-01
      • 2011-09-08
      • 1970-01-01
      • 1970-01-01
      • 2022-08-15
      • 1970-01-01
      相关资源
      最近更新 更多