【问题标题】:Mysterious case constant defined more than once error神秘的案例常量定义不止一次错误
【发布时间】:2017-10-03 18:22:21
【问题描述】:

我正在使用 C 语言商业 RTOS 的套接字库开发一个嵌入式项目。出于保密原因,我将对周围的一些细节非常模糊,但只知道涉及到完整的产品和 RTOS 堆栈。

在我正在处理的部分中,我有一个相当大但简单的 switch 语句,它检查一个宏值并设置另一个宏值。 case 值是来自 RTOS 标头的套接字选项标志。当我用这个 switch 语句编译文件时,我得到一个错误,说“case constant defined more than once”指的是其中的五个案例。

以下是一些让这件事变得神秘的细节:

  1. 所有的标头都用#ifndef HEADER 包裹以避免多次包含。
  2. 宏值来自多个不同的标头,但案例是否产生此错误与源标头之间没有明显的相关性。
  3. 如果我注释掉单个定义或未明确包含该标头,我会得到“未定义标识符”,因此它显然与该文件和定义相关联。
  4. 如果我在 Eclipse 中对宏执行“C/C++”搜索,它会列出定义的两个实例,但都引用同一个文件中的同一个位置。

我在这里由一位高级开发人员运行它,他和我一样感到困惑。有没有人知道可能导致这种情况的 C 解释的怪癖,或者任何地雷都可能被忽视?

谢谢!

【问题讨论】:

  • 表示宏替换和扩展后,有相同整数值的case标签。识别案例标签冲突并找出宏是如何展开的。
  • 不发布代码和相关宏,我们帮不了你。
  • 保密原因无关紧要 - 没有minimal, complete, verifiable example,除了猜测之外,您不可能得到太多帮助。
  • 出于保密原因,您含糊其辞。问题是,这使您的问题如此含糊,以至于没有人可以明智地帮助您。尝试创建一个与您的实际“机密”代码无关的minimal reproducible example,但会出现相同的问题。
  • 虽然很尴尬,但我认为@PaulOgilvie 做到了。事实证明,RTOS 的设计者并不太担心他们的参数一起使用。

标签: c embedded c-preprocessor


【解决方案1】:

错误意味着宏被替换的值对于两个或多个宏是相同的,即使宏本身是不同的。

这是重现此错误的简单方法:

#define ONE 42
#define TWO 42

int main(int argc, char* argv[]) {
    int k = atoi(argv[1]);
    switch (k) {
        case ONE:
            printf("ONE\n");
            break;
        case TWO:
            printf("TWO\n");
            break;
        default:
            printf("NONE\n");
            break;
    }
    return 0;
}

即使宏被称为ONETWO,它们的值都是42,这会导致错误。

【讨论】:

    【解决方案2】:

    所有对宏和标头的引用(几乎)都不是重点:case constant defined more than once 表示您的多个case 语句的计算结果相同,因此编译器无法判断要选择的大小写。

    尝试打印出您的案例标签的实际值(它们都应该计算为整数,因此您可以使用%d 格式对它们进行printf),看看您能否找出为什么您的某些宏具有重叠值.

    【讨论】:

      猜你喜欢
      • 2011-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-27
      • 2011-07-18
      • 1970-01-01
      • 1970-01-01
      • 2015-03-13
      相关资源
      最近更新 更多