Contents
추가적으로, 참고할 내용
http://david.tribble.com/text/cdiffs.htm#C90-aggreg-init c99 의 특징들에 대한 문서. 읽어볼것.
이 문서는
gcc 만의 특징들만을 적어두기 위한 페이지다. gcc 에서만 쓰는 pragma 라든지.. 등등. 원문들은 http://gcc.gnu.org 에서 찾아볼수 있다.
Declarations and Definitions in One Header
C++ object definitions can be quite complex. In principle, your source code will need two kinds of things for each object that you use across more than one source file. First, you need an interface specification, describing its structure with type declarations and function prototypes. Second, you need the implementation itself. It can be tedious to maintain a separate interface description in a header file, in parallel to the actual implementation. It is also dangerous, since separate interface and implementation definitions may not remain parallel.
With GNU C++, you can use a single header file for both purposes.
Warning: The mechanism to specify this is in transition. For the nonce, you must use one of two #pragma commands; in a future release of GNU C++, an alternative mechanism will make these #pragma commands unnecessary.
The header file contains the full definitions, but is marked with #pragma interface in the source code. This allows the compiler to use the header file only as an interface specification when ordinary source files incorporate it with #include. In the single source file where the full implementation belongs, you can use either a naming convention or #pragma implementation to indicate this alternate use of the header file.
#pragma interface #pragma interface "subdir/objects.h"
- Use this directive in header files that define object classes, to save space in most of the object files that use those classes. Normally, local copies of certain information (backup copies of inline member functions, debugging information, and the internal tables that implement virtual functions) must be kept in each object file that includes class definitions. You can use this pragma to avoid such duplication. When a header file containing #pragma interface is included in a compilation, this auxiliary information will not be generated (unless the main input source file itself uses #pragma implementation). Instead, the object files will contain references to be resolved at link time. The second form of this directive is useful for the case where you have multiple headers with the same name in different directories. If you use this form, you must specify the same string to #pragma implementation.
#pragma implementation #pragma implementation "objects.h"
- Use this pragma in a main input file, when you want full output from included header files to be generated (and made globally visible). The included header file, in turn, should use #pragma interface. Backup copies of inline member functions, debugging information, and the internal tables used to implement virtual functions are all generated in implementation files. If you use #pragma implementation with no argument, it applies to an include file with the same basename1 as your source file. For example, in allclass.cc, giving just #pragma implementation by itself is equivalent to #pragma implementation "allclass.h". In versions of GNU C++ prior to 2.6.0 allclass.h was treated as an implementation file whenever you would include it from allclass.cc even if you never specified #pragma implementation. This was deemed to be more trouble than it was worth, however, and disabled. If you use an explicit #pragma implementation, it must appear in your source file before you include the affected header files. Use the string argument if you want a single implementation file to include code from multiple header files. (You must also use #include to include the header file; #pragma implementation only specifies how to use the file--it doesn't actually include it.) There is no way to split up the contents of a single header file into multiple implementation files.
#pragma implementation and #pragma interface also have an effect on function inlining.
- If you define a class in a header file marked with #pragma interface, the effect on a function defined in that class is similar to an explicit extern declaration--the compiler emits no code at all to define an independent version of the function. Its definition is used only for inlining with its callers. Conversely, when you include the same header file in a main source file that declares it as #pragma implementation, the compiler emits code for the function itself; this defines a version of the function that can be found via pointers (or by callers compiled without inlining). If all calls to the function can be inlined, you can avoid emitting the function by compiling with -fno-implement-inlines. If any calls were not inlined, you will get linker errors.
Declaring Attributes of Functions
In GNU C, you declare certain things about functions called in your program which help the compiler optimize function calls and check your code more carefully.
- 여러가지가 있는데, 그중 쓸만한것은 몇개 없는것 같다. 그나마 유용해 보이는듯한놈을 골라 적어본다.
constructor/destructor
- The constructor attribute causes the function to be called automatically before execution enters main (). Similarly, the destructor attribute causes the function to be called automatically after main () has completed or exit () has been called. Functions with these attributes are useful for initializing data that will be used implicitly during the execution of the program.
deprecated
- The deprecated attribute results in a warning if the function is used anywhere in the source file. This is useful when identifying functions that are expected to be removed in a future version of a program. The warning also includes the location of the declaration of the deprecated function, to enable users to easily find further information about why the function is deprecated, or what they should do instead. Note that the warnings only occurs for uses:
int old_fn () __attribute__ ((deprecated)); int old_fn (); int (*fn_ptr)() = old_fn;
Specifying Attributes of Variables
역시 몇가지만 뽑아서 베낀다.
aligned (alignment)
- This attribute specifies a minimum alignment for the variable or structure field, measured in bytes. For example, the declaration:
int x __attribute__ ((aligned (16))) = 0;
struct foo { int x[2] __attribute__ ((aligned (8))); };
short array[3] __attribute__ ((aligned));
Note that the effectiveness of aligned attributes may be limited by inherent limitations in your linker. On many systems, the linker is only able to arrange for variables to be aligned up to a certain maximum alignment. (For some linkers, the maximum supported alignment may be very very small.) If your linker is only able to align variables up to a maximum of 8 byte alignment, then specifying aligned(16) in an attribute will still only provide you with 8 byte alignment. See your linker documentation for further information.
packed
- The packed attribute specifies that a variable or structure field should have the smallest possible alignment--one byte for a variable, and one bit for a field, unless you specify a larger value with the aligned attribute. Here is a structure in which the field x is packed, so that it immediately follows a:
struct foo { char a; int x[2] __attribute__ ((packed)); };
deprecated
- The deprecated attribute results in a warning if the variable is used anywhere in the source file. This is useful when identifying variables that are expected to be removed in a future version of a program. The warning also includes the location of the declaration of the deprecated variable, to enable users to easily find further information about why the variable is deprecated, or what they should do instead. Note that the warnings only occurs for uses:
extern int old_var __attribute__ ((deprecated)); extern int old_var; int new_fn () { return old_var; }
results in a warning on line 3 but not line 2.
Specifying Attributes of Types
역시 쓸만한놈은 deprecated 밖에..
deprecated
- The deprecated attribute results in a warning if the type is used anywhere in the source file. This is useful when identifying types that are expected to be removed in a future version of a program. If possible, the warning also includes the location of the declaration of the deprecated type, to enable users to easily find further information about why the type is deprecated, or what they should do instead. Note that the warnings only occur for uses and then only if the type is being applied to an identifier that itself is not being declared as deprecated.
typedef int T1 __attribute__ ((deprecated)); T1 x; typedef T1 T2; T2 y; typedef T1 T3 __attribute__ ((deprecated)); T3 z __attribute__ ((deprecated));
Function Names as Strings
GCC predefines two magic identifiers to hold the name of the current function. The identifier FUNCTION holds the name of the function as it appears in the source. The identifier PRETTY_FUNCTION holds the name of the function pretty printed in a language specific fashion.
These names are always the same in a C function, but in a C++ function they may be different. For example, this program:
extern "C" { extern int printf (char *, ...); } class a { public: sub (int i) { printf ("__FUNCTION__ = %s\n", __FUNCTION__); printf ("__PRETTY_FUNCTION__ = %s\n", __PRETTY_FUNCTION__); } }; int main (void) { a ax; ax.sub (0); return 0; }
gives this output:
__FUNCTION__ = sub __PRETTY_FUNCTION__ = int a::sub (int)
The compiler automagically replaces the identifiers with a string literal containing the appropriate name. Thus, they are neither preprocessor macros, like FILE and LINE, nor variables. This means that they catenate with other string literals, and that they can be used to initialize char arrays. For example
char here[] = "Function " __FUNCTION__ " in " __FILE__;
On the other hand, #ifdef FUNCTION does not have any special meaning inside a function, since the preprocessor does not do anything special with the identifier FUNCTION.
Note that these semantics are deprecated, and that GCC 3.2 will handle FUNCTION and PRETTY_FUNCTION the same way as func. func is defined by the ISO standard C99:
The identifier __func__ is implicitly declared by the translator as if, immediately following the opening brace of each function definition, the declaration static const char __func__[] = "function-name"; appeared, where function-name is the name of the lexically-enclosing function. This name is the unadorned name of the function.
By this definition, func is a variable, not a string literal. In particular, func does not catenate with other string literals.
In C++, FUNCTION and PRETTY_FUNCTION are variables, declared in the same way as func.
Options That Control Optimization
아주 간략히
-O, -O1
- Optimize. Optimizing compilation takes somewhat more time, and a lot more memory for a large function. With -O, the compiler tries to reduce code size and execution time, without performing any optimizations that take a great deal of compilation time.
-O turns on the following optimization flags:
-fdefer-pop -fmerge-constants -fthread-jumps -floop-optimize -fcrossjumping -fif-conversion -fif-conversion2 -fdelayed-branch -fguess-branch-probability -fcprop-registers
- -O also turns on -fomit-frame-pointer on machines where doing so does not interfere with debugging.
-O2
- Optimize even more. GCC performs nearly all supported optimizations that do not involve a space-speed tradeoff. The compiler does not perform loop unrolling or function inlining when you specify -O2. As compared to -O, this option increases both compilation time and the performance of the generated code. -O2 turns on all optimization flags specified by -O. It also turns on the following optimization flags:
-fforce-mem -foptimize-sibling-calls -fstrength-reduce -fcse-follow-jumps -fcse-skip-blocks -frerun-cse-after-loop -frerun-loop-opt -fgcse -fgcse-lm -fgcse-sm -fdelete-null-pointer-checks -fexpensive-optimizations -fregmove -fschedule-insns -fschedule-insns2 -fsched-interblock -fsched-spec -fcaller-saves -fpeephole2 -freorder-blocks -freorder-functions -fstrict-aliasing -falign-functions -falign-jumps -falign-loops -falign-labels}
-O3
- Optimize yet more. -O3 turns on all optimizations specified by -O2 and also turns on the -finline-functions and -frename-registers options.
-O0
- Do not optimize. This is the default.
-Os
- Optimize for size. -Os enables all -O2 optimizations that do not typically increase code size. It also performs further optimizations designed to reduce code size. -Os disables the following optimization flags:
-falign-functions -falign-jumps -falign-loops -falign-labels -freorder-blocks -fprefetch-loop-arrays
Arrays of Length Zero
- Zero-length arrays are allowed in GNU C. They are very useful as the last element of a structure which is really a header for a variable-length object:
struct line { int length; char contents[0]; }; struct line *thisline = (struct line *) malloc (sizeof (struct line) + this_length); thisline->length = this_length;
- Flexible array members are written as contents[] without the 0.
- Flexible array members have incomplete type, and so the sizeof operator may not be applied. As a quirk of the original implementation of zero-length arrays, sizeof evaluates to zero.
- Flexible array members may only appear as the last member of a struct that is otherwise non-empty.
- A structure containing a flexible array member, or a union containing such a structure (possibly recursively), may not be a member of a structure or an element of an array. (However, these uses are permitted by GCC as extensions.)
struct f1 { int x; int y[]; } f1 = { 1, { 2, 3, 4 } }; struct f2 { struct f1 f1; int data[3]; } f2 = { { 1 }, { 2, 3, 4 } };
struct foo { int x; int y[]; }; struct bar { struct foo z; }; struct foo a = { 1, { 2, 3, 4 } }; // Valid. struct bar b = { { 1, { 2, 3, 4 } } }; // Invalid. struct bar c = { { 1, { } } }; // Valid. struct foo d[1] = { { 1 { 2, 3, 4 } } }; // Invalid.
