Skip to content

Supported compiler specific extensions

guwirth edited this page Mar 23, 2021 · 13 revisions

cxx plugin implements a C++ compatible grammar. Additional below listed compiler specific extensions are supported:

Preprocessor

With GCC's it is allowed to leave the variable argument out entirely

Example:

#define eprintf(format, ...) fprintf (stderr, format, __VA_ARGS__)
eprintf("success!");

Results in:

fprintf(stderr, "success!", );

GCC's special meaning of token paste operator

If variable argument is left out then the comma before the paste operator will be deleted.

Example:

#define eprintf(format, ...) fprintf (stderr, format, ##__VA_ARGS__)
eprintf("success!");

Results in:

fprintf(stderr, "success!");

Parser

GCC's statement expression

A compound statement enclosed in parentheses may appear as an expression in GCC. This allows you to use loops, switches, and local variables within an expression.

Example:

#define maxint(a,b) \
       ({int _a = (a), _b = (b); _a > _b ? _a : _b; })

GCC's Conditionals with Omitted Operands

There is a GCC extension which allows the middle operand in a conditional expression to be omitted. Therefore, the expression 'x ? : y' has the value of x if that is nonzero; otherwise, the value of y.

Example:

... = x ? : y;

GCC's Case Ranges

You can specify a range of consecutive values in a single case label, like this: case low ... high:. This has the same effect as the proper number of individual case labels, one for each integer value from low to high, inclusive. Be careful: Write spaces around the ..., for otherwise it may be parsed wrong when you use it with integer values. For example, write this: case 1 ... 5: rather than this: case 1...5:.

Example:

switch(c) {
   case 'A' ... 'C':
      break;
}

ISO C99: Compound Literals

ISO C99 supports compound literals. A compound literal looks like a cast containing an initializer. Its value is an object of the type specified in the cast, containing the elements specified in the initializer; it is an lvalue.

Example:

struct foo {int a; char b[2];} structure;
structure = ((struct foo) {x + y, 'a', 0});

ISO C99: Designated Initializers

In ISO C99 you can give the elements in any order, specifying the array indices or structure field names they apply to

Example:

int a[6] = { [4] = 29, [2] = 15 }; // is equivalent to: int a[6] = { 0, 0, 15, 0, 29, 0 };

GCC's extension: To initialize a range of elements to the same value, write ‘[first ... last] = value’.

Example:

int widths[] = { [0 ... 9] = 1, [10 ... 99] = 2, [100] = 3 };

In a structure initializer, specify the name of a field to initialize with ‘.fieldname =’ before the element value.

Example:

struct point { int x, y; };
struct point p = { .y = yvalue, .x = xvalue };

Microsoft Visual Studio Inline Assembler support

Visual Studio uses a proprietary __asm keyword which is not standard conform. Use a preprocessor macro to replace __asm with asm.

Syntax:

__asm assembly-instruction [ ; ]
__asm { assembly-instruction-list } [ ; ]

Example:

#define __asm asm
__asm {
   mov eax, num
   mov ecx, power
   shl eax, cl
}
__asm mov array[6], bx ;
__asm mov array[6], bx // without ; at the end is currently not supported by cxx plugin

Microsoft Visual Studio Attributted ATL support

There is a special flavor of ATL called Attributed ATL or ATL and Attributes. The attributes were added to make programming ATL simpler. The attributes would typically lead to source code insertion.

Example:

[
    object,
    uuid("2543548B-EFFB-4CB4-B2ED-9D3931A2527D"),
    dual,
    oleautomation,
    nonextensible,
    hidden,
    helpstring("IServicesMgr Interface"),
    pointer_default(unique)
]
__interface IMyInterface : IDispatch
{
  [id(1), helpstring("method Start")] HRESULT Start([in] BSTR ServiceName);
  [id(2), helpstring("method Stop")] HRESULT Stop([in] BSTR ServiceName);
};
Clone this wiki locally