This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TMS320F28P650DK:C2000 编译器未能对重复的全局变量给出错误

Guru**** 2952510 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1653960/tms320f28p650dk-c2000-compiler-fails-to-give-error-on-duplicate-global-variables

器件型号: TMS320F28P650DK

编译函数:

long func (void)
{
长 x、x、x、x;
x=1;
返回 x;
}
给出错误:错误 #102:“x“已在当前范围内声明

但是、下面一行全局声明变量(在函数之外)不会导致任何警告或错误:

长 x、x、x、x;

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Alon:

    这种行为几乎肯定不是编译器错误 — 这是 C 语言标准如何处理文件作用域和块作用域中的声明的结果。

    为什么会发生这种情况:C 中的暂定定义

    在 C 标准 (C89/C99/C11) 中、不带初始化值的文件范围(全局)处的声明被视为 暂定定义。 该标准明确允许在单个翻译单元中对同一标识符进行多个暂定定义、只要它们是兼容的类型即可。 在翻译单元结束时、如果没有外部定义出现、暂定定义将成为完整的定义。

    因此、以下位于文件范围:

    长 x、x、x、x;

    相当于写入:

    长 x;
    长 x;
    长 x;
    长 x;
    长 x;

    这每一个都是 C 标准下有效的暂定定义、编译器 不能将其标记为错误是正确的。

    为什么函数中出现错误

    在块(函数体)内部、声明 不是 暂定定义—它们是受以下规则约束的普通声明:标识符不能在同一范围内多次声明。 因此、针对以下情况正确发出了错误#102:

    long func (void){long x、x、x、x; //错误#102}

    大家可以做的

    • 启用更严格的模式: 如果 C2000 编译器支持某个 --strict_ansi 或类似的标志、或者如果您可以在 C++模式下编译、则可能会标记重复的文件作用域声明。
    • 使用初始化程序: 如果您 long x = 0, x = 0; 在文件范围内编写文件,这会产生错误 ,因为您会有多个同一对象的外部定义,这违反了一个定义规则。
    • 静态分析工具: 如 PC-Lint 或 Polyspace 等工具在代码库中无意捕获此模式。

    摘要

    编译器的行为符合 C 语言标准。 文件作用域和块作用域行为之间的不对称性是 C 语言暂定定义规则的众所周知的细微之处、不是 C2000 工具链的缺陷。


    为了帮助进一步确认这一点、了解以下信息会很有用:

    • 您使用的 C2000 编译器版本和内部版本号
    • 无论您是在 C89、C99 还是 C11 模式下编译(例如,FLAG) --c99
    • 是否启用 --strict_ansi 或提高诊断级别(例如) --diag_warning会改变行为

    这些详细信息可以帮助确定是否有办法让编译器针对该模式至少发出警告(即使其在技术上符合标准)。

    此致、

    Zackary Fleenor