c语言用中括号括起来的变量,c语言中用括号将花括号括起来给变量赋值

#define max(x,y) ({ \

typeof(x) _x = (x);\

typeof(y) _y = (y);\

(void) (&_x == &_y);\

_x > _y ? _x : _y; })express

在这个宏中,花括号里表达式的值为最后一条语句的值,而后用小括号将大括号括起来就能够给其余变量赋值了。当红语句中的最外层小括号不用的话,也就是若是这个宏语句改成以下时:app

#define max(x,y)  { \

typeof(x) _x = (x);\

typeof(y) _y = (y);\

(void) (&_x == &_y);\ide

_x > _y ? _x : _y; }oop

就会出现错误。具体为何会出现这样的状况本人也不是很清楚。但在网上看到一个这样的介绍:post

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 )

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 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值