是否存在可以在不执行任何操作时使用的虚拟左值?

Gau*_*ier 5 c embedded language-lawyer

考虑以下C99功能:

void port_pin_set(const bool value, const uint8_t pin_mask)
{
    if (value) {
        PORT |= pin_mask;
    } else {
        PORT &= ~pin_mask;
    }
}
Run Code Online (Sandbox Code Playgroud)

PORTa define为例,例如:

#define PORT (P1OUT)
Run Code Online (Sandbox Code Playgroud)

有没有办法重新定义,PORT以便:

  • 它被接受为左值,
  • 该功能不做任何事情.

我想要做的是保持功能源不变,同时编译它不做任何事情.

编辑:我知道使用这样的左值可能不是最好的解决方案.我不是在寻找这个特定问题的最佳解决方案,我对语言本身很感兴趣.这是一个理论问题,而不是务实的问题.

Jen*_*edt 10

C99具有可用于此类任务的复合文字.它们的语法是一个强制转换后跟一个初始化器:

#define PORT ((int){0})
Run Code Online (Sandbox Code Playgroud)

应该在你的情况下这样做,只是你可能会得到一些关于未使用值的警告.

任何体面的编译器都会优化对这种复合文字的赋值.


das*_*ght 8

您可以定义与您的P1OUT(例如unsigned char)相同类型的变量,使其在标题中可用,并在其中一个源中定义它,如下所示:

标题:

extern unsigned char dummy_P1OUT;
#define PORT (dummy_P1OUT)
Run Code Online (Sandbox Code Playgroud)

C档案:

unsigned char dummy_P1OUT;
Run Code Online (Sandbox Code Playgroud)

用途:

PORT &= ~pin_mask;

if (PORT & pin_mask) {
    blink_led();
}
Run Code Online (Sandbox Code Playgroud)

  • @aix我读"编译它什么都不做"不同于"强制编译器不生成代码":我对OP的意图的理解是他希望结果不会改变与他的程序相关的东西,类似于转发输出UNIX上的`/ dev/null`程序. (3认同)
  • @JensGustedt C99的复合文字是很好的,我同意如果在编译器中有支持,应该使用它们.然而,嵌入式世界中的编译器传统上落后于主流版本:我记得在九十年代后期使用ANSI之前的嵌入式编译器,甚至那些声称ANSI兼容性的编译器有时会对新的ANSI语法行为不端.不幸的是,我不记得细节 - 我已经离开嵌入式世界十多年了.但是,当我看到"嵌入式"时,我读到"古老",并且更喜欢兼容的解决方案而不是新的解决方案. (2认同)