【问题标题】:Is this enumeration construct and assignment allowed?这个枚举构造和赋值是否允许?
【发布时间】:2016-10-25 19:06:01
【问题描述】:

这是否可以在 Linux GCC 下编译和工作?

在 Github 上托管的 LoRa 网关堆栈中,我在 loragw_hal.h 中找到了以下构造

enum lgw_radio_type_e {
    LGW_RADIO_TYPE_NONE,
    LGW_RADIO_TYPE_SX1255,
    LGW_RADIO_TYPE_SX1257
};

#define LGW_RF_CHAIN_NB     2   /* number of RF chains */

然后在 loragw_hal.c

static enum lgw_radio_type_e rf_radio_type[LGW_RF_CHAIN_NB];

编辑:数组在代码中的任何地方都没有初始化

然后在函数中

setup_sx125x(uint8_t rf_chain, uint32_t freq_hz)

以下switch语句用于根据rf_chain参数选择rf链

switch (rf_radio_type[rf_chain]) {
    case LGW_RADIO_TYPE_SX1255:
        // some code
        break;
    case LGW_RADIO_TYPE_SX1257:
        // some code
        break;
    default:
        DEBUG_PRINTF("ERROR: UNEXPECTED VALUE %d FOR RADIO TYPE\n", 
        rf_radio_type[rf_chain]);
        break;
}

rf_chain 参数设置为 1,当函数被调用时,它当然会选择默认的 Error 'unexpected rf chain'。

版权持有者 Semtech Inc. 的支持始终指向此代码,如果您对其产品有任何问题,请作为参考。

但我有一种感觉,如果不进行任何修改,这段代码无论如何都不会运行。

所以我在这里向论坛提出的问题是,除了上面的这个构造没有真正意义之外,这不是一个错误的构造吗?

这是否可以在 Linux GCC 下编译和工作?

我尝试在 GCC ARM 下使用此代码,但它似乎没有按计划工作。

【问题讨论】:

  • 代码看起来一切正常,但switchrf_radio_type[1] 中的值上,而不是在1 上...并且显示的代码都没有设置数组中的值。
  • 正确,数组没有初始化,无论如何,我认为更糟糕的是,因为如果为 rf_radio_type 分配的空间没有初始化为 NULL,这可能会像彩票一样出来
  • 我看不出您提供的代码有任何本质上的错误或荒谬之处。值得怀疑的是,switch 没有明确的LGW_RADIO_TYPE_NONE 案例,但也许该替代方案以不同的方式处理。您对代码有具体的顾虑吗?
  • 实际上,由于数组是static,它的元素最初被归零(LGW_RADIO_TYPE_NONE)......但没有显示将它们设置为其他任何东西。
  • "* ...它并没有按计划工作*" -- 那么它做什么呢?

标签: c linux gcc lora


【解决方案1】:

你似乎想引起人们的注意:

enum lgw_radio_type_e {
    LGW_RADIO_TYPE_NONE,
    LGW_RADIO_TYPE_SX1255,
    LGW_RADIO_TYPE_SX1257
};

#define LGW_RF_CHAIN_NB     2   /* number of RF chains */

[...]

static enum lgw_radio_type_e rf_radio_type[LGW_RF_CHAIN_NB];

[...] 代码中的任何地方都没有初始化数组

数组没有被显式初始化并不是一个特殊的问题。如果未提供显式初始化程序,则文件范围变量(和static 块范围变量)将接受默认初始化。在这种情况下,数组声明等价于

static enum lgw_radio_type_e rf_radio_type[2] = {
        LGW_RADIO_TYPE_NONE, LGW_RADIO_TYPE_NONE
    };

这本身似乎很明智。

你接着说,

[...] 当函数被调用时,它当然会选择默认的错误'unexpected rf chain'。

我看不出有任何理由期望选择不同的案例,但我也看不出有任何理由假设会不会选择不同的案例。也不清楚switch本身是在什么情况下执行的。

如果事实上存在相应的硬件,人们通常会期望在驱动程序初始化期间设置rf_radio_type 的一个或两个元素。如果整体代码(不仅仅是您提供的部分)是正确的,那么当rf_radio_type[rf_chain] 的值不同于LGW_RADIO_TYPE_SX1255 和@ 时,它可能不会执行提供的switch 987654330@。另一方面,打印错误信息本身基本上是无害的。如果驱动程序打印了它,那么这可能只是实施质量问题,而不是功能缺陷。

所以我在这里向论坛提出的问题是,除此之外 上面说的不是很有意义,这不是一个错误的构造吗?

不,不是。据我所知,所有提出的结构在脱离上下文时都尽可能地有意义。

这是否可以在 Linux GCC 下编译和工作?

您已经提供了几个单独有效的 C 片段,但它们不一起构成一个有效的翻译单元。可以形成一个完整的、有效的翻译单元,其中包含所有可以成功编译并执行任何操作的片段。片段本身不会干扰编译,也不一定会导致故障。

我尝试在 GCC ARM 下使用此代码,但它似乎没有按计划工作。

我发现您对您对整体代码预期行为的评估的明显信心有点乐观。

【讨论】:

    【解决方案2】:

    编辑:数组在代码中的任何地方都没有初始化

    正如另一个答案中所指出的,如果程序员没有明确设置它们,C 标准要求具有静态存储持续时间的变量隐式初始化为零。所以就 C 标准而言,这是代码。

    然而,在.bss 中编写依赖于静态存储持续时间变量初始化的代码在嵌入式系统编程中被认为是不好的做法。这是因为在嵌入式系统上经常会省略复制.data 和零初始化.bss 的代码,这是一种非常常见的非标准做法,以加快程序启动速度。

    这样的非标准选项在编译器选项中通常称为“最小/紧凑/快速启动”或类似名称。如果您启用了这样的选项 - 这很常见 - 代码将无法正常工作。

    好的做法是在“运行时”稍后在它们第一次使用之前初始化这些变量。

    总结:代码写得很草率,因为这里的目的是提供跨许多不同微控制器平台的可移植代码,而不是为某些 PC 提供代码。我猜它是由某种 PC 程序员编写的,就像这些协议栈的情况一样。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-02-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多