免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 17822 | 回复: 2
打印 上一主题 下一主题

C语言花括号表达式 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-02-29 15:30 |只看该作者 |倒序浏览

  1. int y;
  2. y = ({
  3.         int x = 0;
  4.         x++;
  5.         x;
  6. });
复制代码
C语言的花括号可以这样用?
我知道花括号可以形成一个局部作用域,这样就可以声明一个局部变量。
但我不知道的是用括号把花括号括起来之后还能当做一个表达式来用

论坛徽章:
0
2 [报告]
发表于 2012-02-29 16:06 |只看该作者
gcc的扩展用法,标准C++不支持。

它相当于是扩展了primary-expression
   primary-expression:
     identifier
     constant
     string-literal
     ( expression )

   GNU extensions:

   primary-expression:
     __func__
       (treated as a keyword in GNU C)
     __FUNCTION__
     __PRETTY_FUNCTION__
     ( compound-statement )         // compound-statement 就是花括号语句
     __builtin_va_arg ( assignment-expression , type-name )
     __builtin_offsetof ( type-name , offsetof-member-designator )
     __builtin_choose_expr ( assignment-expression ,
                             assignment-expression ,
                             assignment-expression )
     __builtin_types_compatible_p ( type-name , type-name )

论坛徽章:
0
3 [报告]
发表于 2012-02-29 16:33 |只看该作者
6 Extensions to the C Language Family
GNU C provides several language features not found in ISO standard C. (The ‘-pedantic’
option directs GCC to print a warning message if any of these features is used.) To test for
the availability of these features in conditional compilation, check for a predefined macro
__GNUC__, which is always defined under GCC.
These extensions are available in C and Objective-C. Most of them are also available in
C++. See Chapter 7 [Extensions to the C++ Language], page 581, for extensions that apply
only to C++.
Some features that are in ISO C99 but not C90 or C++ are also, as extensions, accepted
by GCC in C90 mode and in C++.

6.1 Statements and Declarations in Expressions
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.
Recall that a compound statement is a sequence of statements surrounded by braces; in
this construct, parentheses go around the braces. For example:
({ int y = foo (); int z;
if (y > 0) z = y;
else z = - y;
z; })
is a valid (though slightly more complex than necessary) expression for the absolute value
of foo ().
The last thing in the compound statement should be an expression followed by a semi-
colon; the value of this subexpression serves as the value of the entire construct. (If you use
some other kind of statement last within the braces, the construct has type void, and thus
effectively no value.)
This feature is especially useful in making macro definitions “safe” (so that they evaluate
each operand exactly once). For example, the “maximum” function is commonly defined
as a macro in standard C as follows:
#define max(a,b) ((a) > (b) ? (a) : (b))
But this definition computes either a or b twice, with bad results if the operand has side
effects. In GNU C, if you know the type of the operands (here taken as int), you can define
the macro safely as follows:
#define maxint(a,b) \
({int _a = (a), _b = (b); _a > _b ? _a : _b; })
Embedded statements are not allowed in constant expressions, such as the value of an
enumeration constant, the width of a bit-field, or the initial value of a static variable.
If you don’t know the type of the operand, you can still do this, but you must use typeof
(see Section 6.6 [Typeof ], page 296).
In G++, the result value of a statement expression undergoes array and function pointer
decay, and is returned by value to the enclosing expression. For instance, if A is a class,
then290 Using the GNU Compiler Collection (GCC)
A a;
({a;}).Foo ()
will construct a temporary A object to hold the result of the statement expression, and that
will be used to invoke Foo. Therefore the this pointer observed by Foo will not be the
address of a.
Any temporaries created within a statement within a statement expression will be de-
stroyed at the statement’s end. This makes statement expressions inside macros slightly
different from function calls. In the latter case temporaries introduced during argument
evaluation will be destroyed at the end of the statement that includes the function call. In
the statement expression case they will be destroyed during the statement expression. For
instance,
#define macro(a) ({__typeof__(a) b = (a); b + 3; })
template<typename T> T function(T a) { T b = a; return b + 3; }
void foo ()
{
macro (X ());
function (X ());
}
will have different places where temporaries are destroyed. For the macro case, the tem-
porary X will be destroyed just after the initialization of b. In the function case that
temporary will be destroyed when the function returns.
These considerations mean that it is probably a bad idea to use statement-expressions of
this form in header files that are designed to work with C++. (Note that some versions of
the GNU C Library contained header files using statement-expression that lead to precisely
this bug.)
Jumping into a statement expression with goto or using a switch statement outside the
statement expression with a case or default label inside the statement expression is not
permitted. Jumping into a statement expression with a computed goto (see Section 6.3
[Labels as Values], page 291) yields undefined behavior. Jumping out of a statement ex-
pression is permitted, but if the statement expression is part of a larger expression then
it is unspecified which other subexpressions of that expression have been evaluated except
where the language definition requires certain subexpressions to be evaluated before or after
the statement expression. In any case, as with a function call the evaluation of a statement
expression is not interleaved with the evaluation of other parts of the containing expression.
For example,
foo (), (({ bar1 (); goto a; 0; }) + bar2 ()), baz();
will call foo and bar1 and will not call baz but may or may not call bar2. If bar2 is called,
it will be called after foo and before bar1
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP