模拟 GCC 语句表达式
Emulating GCC Statement Expressions
嵌入式项目被迫使用IAR EW430编译器v7.12,官方只支持c99
除了编写一堆专用的内联函数之外,我希望能够以一般方式模拟 GCC 的语句表达式。
有什么办法可以实现吗? (也许使用 MACRO-wizardry?或者模拟 Lambdas,或者一些允许这样做的隐藏编译器开关?)显然除了改变编译器之外。
具体来说,复合表达式的最后一条语句的结果应该把它的类型和值都带出来,而不是作为宏参数传入。
我已经搜索了几个月,但我能找到的最接近的是令人印象深刻的 impressive library,但这似乎太多了。
我知道这不是你要找的答案,但既然你问了 "Is there any way to achieve this?",我不得不说答案只是 "No".
不要误会我的意思 -- 我知道您在寻找什么,也知道您为什么想要它。这是一个非常酷的功能。曾几何时,我试图发明我自己的类 C 语言,我的目标之一是每个语句都可以用作表达式。但是这个特性根本不是 C 的一部分,也没有像样的方法来模拟它。
事实上,您可以很容易地证明没有合适的方法来模拟它,因为如果有,gcc 人员就不必实施那些疯狂的非标准扩展。
因此,如果您想使用 gcc 及其扩展,请务必使用 gcc 及其扩展。但是如果你想用相当纯的 C 编写,你将不得不学会在没有语句表达式的情况下生活。 "When in Rome, do as the Romans do." 你用疯狂的宏魔法设法实现的任何东西都可能 (a) 无法真正满足你对真实语句表达式的渴望,并且 (b) 让你的程序维护成为任何追随你但不理解的人的噩梦他们有什么了不起的。
你说你在做嵌入式工作,但你确定你的平台没有 gcc 端口吗? (我知道你说你 "forced to" 使用 IAR,但你也说这是一个 "toy project",所以也许你可以打破那个规则。IAR 总是让我想起维基百科的口号 "Ignore All Rules" 无论如何。:-) )
但是既然你说你在做嵌入式工作,那就是阻止这种超前特性的另一个原因。我得到的印象是 "embedded work" 的定义特征之一是它试图无论如何都拒绝使用一半的语言,强制只使用定义非常明确、非常安全的子集。所以我怀疑像语句表达式这样的扩展是否适用于您的项目。
在评论中,您澄清
My intent is to truly (or as closely as possible) emulate Statement
Expressions, to be used in every way that they can be used, with every
property they have.
因此,让我们看看语句表达式是如何形成的以及它们的作用:
A compound statement enclosed in parentheses may appear as an
expression in GNU C. This allows you to use loops, switches, and local
variables within an expression.
[...]
The last thing in the compound statement should be an expression
followed by a semicolon; the value of this subexpression serves as the
value of the entire construct.
其中有两个关键部分:
构造围绕复合语句构建,因此可以包含复合语句可以包含的任何内容。
构造计算出一个值。
而且你明确的说
Specifically, the result of the last statement of the compound
expression should carry both its type AND value out, not have those
passed in as a macro parameter.
你把自己画到墙角了。 C 语句 不是 表达式,这恰恰意味着它们不求值。这就是为什么 GCC 语句表达式是一个扩展。值没有链接,并且在可以被认为具有范围的范围内,它仅限于它们出现的表达式和存储它们的对象。将值从语句中转移出来的唯一方法是将其分配给适当类型的对象(并且您明确希望避免这样做)或分配给 return
它(这要求它在函数中)。
语句表达式的其他特征可能首先引起了您的兴趣。特别是,由于您提出了 lambda,我怀疑您对以下事实感兴趣:语句表达式存在于周围代码的上下文中,因此除其他外,它们可以使用那里范围内的标识符。如果这就是您所追求的,那么您可能只需要编写普通的代码块,并提供报告结果的变量。
但是,还有另一种选择可以为您提供 一点 您想要的东西。您可以依次计算多个表达式,通过使用逗号运算符,每个表达式都可以利用前一个表达式的副作用。例如,
int first = 1, second = 2, temp, new_first;
new_first = (temp = second, second = first, first = temp);
结果是 first
和 second
的值被交换,first
的新值被分配给 new_first
。当然,这不提供循环、if
语句、 等,尤其不提供声明局部变量,例如temp
。正如我所说,稍微 了解语句表达式的作用。
嵌入式项目被迫使用IAR EW430编译器v7.12,官方只支持c99
除了编写一堆专用的内联函数之外,我希望能够以一般方式模拟 GCC 的语句表达式。
有什么办法可以实现吗? (也许使用 MACRO-wizardry?或者模拟 Lambdas,或者一些允许这样做的隐藏编译器开关?)显然除了改变编译器之外。
具体来说,复合表达式的最后一条语句的结果应该把它的类型和值都带出来,而不是作为宏参数传入。
我已经搜索了几个月,但我能找到的最接近的是令人印象深刻的 impressive library,但这似乎太多了。
我知道这不是你要找的答案,但既然你问了 "Is there any way to achieve this?",我不得不说答案只是 "No".
不要误会我的意思 -- 我知道您在寻找什么,也知道您为什么想要它。这是一个非常酷的功能。曾几何时,我试图发明我自己的类 C 语言,我的目标之一是每个语句都可以用作表达式。但是这个特性根本不是 C 的一部分,也没有像样的方法来模拟它。
事实上,您可以很容易地证明没有合适的方法来模拟它,因为如果有,gcc 人员就不必实施那些疯狂的非标准扩展。
因此,如果您想使用 gcc 及其扩展,请务必使用 gcc 及其扩展。但是如果你想用相当纯的 C 编写,你将不得不学会在没有语句表达式的情况下生活。 "When in Rome, do as the Romans do." 你用疯狂的宏魔法设法实现的任何东西都可能 (a) 无法真正满足你对真实语句表达式的渴望,并且 (b) 让你的程序维护成为任何追随你但不理解的人的噩梦他们有什么了不起的。
你说你在做嵌入式工作,但你确定你的平台没有 gcc 端口吗? (我知道你说你 "forced to" 使用 IAR,但你也说这是一个 "toy project",所以也许你可以打破那个规则。IAR 总是让我想起维基百科的口号 "Ignore All Rules" 无论如何。:-) )
但是既然你说你在做嵌入式工作,那就是阻止这种超前特性的另一个原因。我得到的印象是 "embedded work" 的定义特征之一是它试图无论如何都拒绝使用一半的语言,强制只使用定义非常明确、非常安全的子集。所以我怀疑像语句表达式这样的扩展是否适用于您的项目。
在评论中,您澄清
My intent is to truly (or as closely as possible) emulate Statement Expressions, to be used in every way that they can be used, with every property they have.
因此,让我们看看语句表达式是如何形成的以及它们的作用:
A compound statement enclosed in parentheses may appear as an expression in GNU C. This allows you to use loops, switches, and local variables within an expression.
[...]
The last thing in the compound statement should be an expression followed by a semicolon; the value of this subexpression serves as the value of the entire construct.
其中有两个关键部分:
构造围绕复合语句构建,因此可以包含复合语句可以包含的任何内容。
构造计算出一个值。
而且你明确的说
Specifically, the result of the last statement of the compound expression should carry both its type AND value out, not have those passed in as a macro parameter.
你把自己画到墙角了。 C 语句 不是 表达式,这恰恰意味着它们不求值。这就是为什么 GCC 语句表达式是一个扩展。值没有链接,并且在可以被认为具有范围的范围内,它仅限于它们出现的表达式和存储它们的对象。将值从语句中转移出来的唯一方法是将其分配给适当类型的对象(并且您明确希望避免这样做)或分配给 return
它(这要求它在函数中)。
语句表达式的其他特征可能首先引起了您的兴趣。特别是,由于您提出了 lambda,我怀疑您对以下事实感兴趣:语句表达式存在于周围代码的上下文中,因此除其他外,它们可以使用那里范围内的标识符。如果这就是您所追求的,那么您可能只需要编写普通的代码块,并提供报告结果的变量。
但是,还有另一种选择可以为您提供 一点 您想要的东西。您可以依次计算多个表达式,通过使用逗号运算符,每个表达式都可以利用前一个表达式的副作用。例如,
int first = 1, second = 2, temp, new_first;
new_first = (temp = second, second = first, first = temp);
结果是 first
和 second
的值被交换,first
的新值被分配给 new_first
。当然,这不提供循环、if
语句、 等,尤其不提供声明局部变量,例如temp
。正如我所说,稍微 了解语句表达式的作用。