Studying note of GCC-3.4.6 source (25)

3.3.3.1.1.            Options for C++

For C/C++ or obj-C, handle_options of lang_hooks is the same as c_common_handle_option. In below, OPT_* is used as index into cl_options.

 

251  int

252  c_common_handle_option (size_t scode, const char *arg, int value)                in c-opts.c

253  {

254    const struct cl_option *option = &cl_options[scode];

255    enum opt_code code = (enum opt_code) scode;

256    int result = 1;

257 

258    switch (code)

259    {

260      default:

261        result = permit_fortran_options;

262        break;

263 

264      case OPT__output_pch_:

265        pch_file = arg;

266        break;

267 

268      case OPT_A:

269        defer_opt (code, arg);

270        break;

271 

272      case OPT_C:

273        cpp_opts->discard_comments = 0;

274        break;

275 

276      case OPT_CC:

277        cpp_opts->discard_comments = 0;

278        cpp_opts->discard_comments_in_macro_exp = 0;

279        break;

280 

281      case OPT_D:

282        defer_opt (code, arg);

283        break;

284 

285      case OPT_E:

286        flag_preprocess_only = 1;

287        break;

288 

289      case OPT_H:

290        cpp_opts->print_include_names = 1;

291        break;

292 

293      case OPT_I:

294        if (strcmp (arg, "-"))

295          add_path (xstrdup (arg), BRACKET, 0);

296        else

297        {

298          if (quote_chain_split)

299            error ("-I- specified twice");

300          quote_chain_split = true;

301          split_quote_chain ();

302        }

303        break;

304 

305      case OPT_M:

306      case OPT_MM:

307        /* When doing dependencies with -M or -MM, suppress normal

308          preprocessed output, but still do -dM etc. as software

309          depends on this. Preprocessed output does occur if -MD, -MMD

310          or environment var dependency generation is used.  */

311        cpp_opts->deps.style = (code == OPT_M ? DEPS_SYSTEM: DEPS_USER);

312        flag_no_output = 1;

313        cpp_opts->inhibit_warnings = 1;

314        break;

315 

316      case OPT_MD:

317      case OPT_MMD:

318        cpp_opts->deps.style = (code == OPT_MD ? DEPS_SYSTEM: DEPS_USER);

319        deps_file = arg;

320        break;

321 

322      case OPT_MF:

323        deps_seen = true;

324        deps_file = arg;

325        break;

 

At line 265, pch_file indicates the file name to which we should write a precompiled header, or NULL if no header will be written in this compile.

At line 268, -Aquestion[=answer] specifies a question and answer for an assertion in the following form:

#if #question(answer)

This option can be written as –assert for –A too.

Also at line 281, -Dmacro[=string], if the string is specified, a macro by that name is defined just as if it had been included as part of the code. For example, -Dbrunt=logger generates the following definition:

#define brunt=logger

If the string is not specified, the macro is defined as the string “1”. For example, -Dminke generates the following definition:

#define minke 1

All -D options are processed before any -U options, and all -U options are processed before any -include or -imacros options.

Both –A and –D switches are handled by defer_opt, notice that arg points to the string after -A or -D.

 

179  static void

180  defer_opt (enum opt_code code, const char *arg)                                          in c-opts.c

181  {

182    deferred_opts[deferred_count].code = code;

183    deferred_opts[deferred_count].arg = arg;

184    deferred_count++;

185  }

 

deferred_opts holds switches parsed by c_common_handle_option, but whose handling is deferred to c_common_post_options.

If flag_preprocess_only (–E) holds, stops after preprocessing the source code and output the result. The output is written to standard out unless the -o option is used to send it to a file. Input files that do not require preprocessing are ignored, which is determined either by the file name suffixes or by not having their types indicated by the -x option. This option defines the environment variables __GNUC__, __GNUC_MINOR__, and __GNUC_PATCHLEVEL__.

Option –H prints a nested listing of all the header files used, along with a list of the ones that are missing a multiple include guard. This option can be written as --trace-includes too.

For –I path switch, add_path is invoked to include the parameter. The “include” path information is saved into cpp_dir which has definition as following.

 

402  struct cpp_dir                                                                                             in cpplib.h

403  {

404   /* NULL-terminated singly-linked list.  */

405    struct cpp_dir *next;

406 

407    /* NAME of the directory, NUL-terminated.  */

408    char *name;

409    unsigned int len;

410 

411    /* One if a system header, two if a system header that has extern

412      "C" guards for C++.  */

413    unsigned char sysp;

414 

415    /* Mapping of file names for this directory for MS-DOS and related

416      platforms. A NULL-terminated array of (from, to) pairs.  */

417    const char **name_map;

418 

419   /* The C front end uses these to recognize duplicated

420      directories in the search path.  */

421    ino_t ino;

422    dev_t dev;

423  };

 

In the system, header files included are grouped into 4 classes. One is included by “”, one is included by <>, one indicates the header file is system ones, the last indicates the header file included by switch -idirafter. So in below, heads and tails are arrays of size 4. Each pair maintains a list of header files’ path of specified class by pointing to the head and tail respectively.

 

303  void

304  add_path (char *path, int chain, int cxx_aware)                                            in c-inpath.c

305  {

306    struct cpp_dir *p;

307 

308  #if defined (HAVE_DOS_BASED_FILE_SYSTEM)

309    /* Convert all backslashes to slashes. The native CRT stat()

310      function does not recognise a directory that ends in a backslash

311      (unless it is a drive root dir, such "c:/"). Forward slashes,

312      trailing or otherwise, cause no problems for stat().  */

313    char* c;

314    for (c = path; *c; c++)

315      if (*c == '//') *c = '/';

316  #endif

317 

318    p = xmalloc (sizeof (struct cpp_dir));

319    p->next = NULL;

320    p->name = path;

321    if (chain == SYSTEM || chain == AFTER)

322      p->sysp = 1 + !cxx_aware;

323    else

324      p->sysp = 0;

325 

326    if (tails[chain])

327      tails[chain]->next = p;

328    else

329      heads[chain] = p;

330    tails[chain] = p;

331  }

 

Above, at line 322 and 324, for the meaning of sysp, refers to line 411 in definition of cpp_dir. Then for switch -I-, which specifies to not look for other source files in the same directory as the source file named on the command line to be compiled. So split_quote_chain is invoked to remove paths included by “”. Notice that it contains memory leak problem.

 

290  void

291  split_quote_chain (void)                                                                              in c-inpath.c

292  {

293    heads[QUOTE] = heads[BRACKET];

294    tails[QUOTE] = tails[BRACKET];

295    heads[BRACKET] = NULL;

296    tails[BRACKET] = NULL;

297   /* This is NOT redundant.  */

298    quote_ignores_source_dir = true;

299  }

 

Above at line 305 in c_common_handle_option, with -M switch the preprocessor outputs a rule suitable for inclusion in a makefile. The rule is composed of the object file name, a colon, the name of the source file and the name of the included files. The include files are listed on separate lines by their full path names. If the –include or -imacros options are on the command line, those files are also in the list. The -M option implies -E.

The resulting rule contains the name of the object file and the list of dependencies; it does not include a rule to compile the source. Unless either the -MT or -MQ option is used to specify the name, the object file name in the produced rule is the same as the input source with the suffix replaced.

The other preprocessor options involved with producing makefile rules are -MD, -MMD, -MF, -MG, -MM, -MP, -MQ, and -MT.

At line 311, -MM is similar with –M, except no system header files are listed.

For –MG, this option can be used in conjunction with -M or -MM to specify that missing header files are assumed to be generated files that reside in the same directory as the source file. The dependency list is generated just as if the header file existed and included no other headers.

For –MP, used in conjunction with -M or -MM to produce a dummy target for each include file. The only purpose of this is to prevent make from generating error messages when you remove a header file without updating the makefile.

Then at line 323, deps_seen indicates if dependency switches (-MF etc.) have been given. –MF filename, when used with -M, -MM, -MD, or -MMD, this option specifies the name of the output file to write the dependencies to. An alternative way of specifying the name of the output file is to set the environment variable DEPENDENCIES_OUTPUT.

At line 337, -MQ target, this option is the same as -MT except the target name is quoted appropriately for the makefile. For example, the command gcc -M –MQ '$(OBJMRK)mrk.o' brink.c will produce the following:

$$(OBJMRK)mrk.o: brink.c

Then –MT target, used in conjunction with -M or -MM to specify the name of the target file of the produced makefile rule. By default, the target file is the same name as the input source file with a .o suffix appended to it. The -MT option can be used to specify a different name, a complete path name, or a name based on an environment variable. For example, the command gcc -M -MT '$(OBJMRK)mrk.o' brink.c will produce the following:

$(OBJMRK)mrk.o: brink.c

flag_no_line_commands (-P) if nonzero, the preprocessor is not to generate #line directives when used with the -E option.

At line 348, flag_working_directory (-fworking-directory) if 0, means we want the preprocessor to not emit line directives for the current working directory, if 1 means we want it to do it, and -1 means we should decide depending on whether debugging information is being emitted or not (the default value is -1).

For –Umacro, if macro has been previously defined, the macro definition is removed. All -D options are processed before any -U options, and all -U options are processed before any -include or -imacros options. The handling is deferred to c_common_post_options.

At line 356, warn_abi (-Wabi) if nonzero, means warn about things that will change when compiling with an ABI-compliant compiler (the default value is 0). [6] gives out the examples of the imcompliant of ABI of G++, however by my testing, these imcompliances have been fixed in current version.

 

c_common_handle_option (continue)

 

327      case OPT_MG:

328        deps_seen = true;

329        cpp_opts->deps.missing_files = true;

330        break;

331 

332      case OPT_MP:

333        deps_seen = true;

334        cpp_opts->deps.phony_targets = true;

335        break;

336 

337      case OPT_MQ:

338      case OPT_MT:

339        deps_seen = true;

340        defer_opt (code, arg);

341        break;

342 

343      case OPT_P:

344        flag_no_line_commands = 1;

345        break;

346 

347      case OPT_fworking_directory:

348        flag_working_directory = value;

349        break;

350 

351      case OPT_U:

352        defer_opt (code, arg);

353        break;

354 

355      case OPT_Wabi:

356        warn_abi = value;

357        break;

358 

359      case OPT_Wall:

360        set_Wunused (value);

361        set_Wformat (value);

362        set_Wimplicit (value);

363        warn_char_subscripts = value;

364        warn_missing_braces = value;

365        warn_parentheses = value;

366        warn_return_type = value;

367        warn_sequence_point = value;   /* Was C only.  */

368        if (c_dialect_cxx ())

369          warn_sign_compare = value;

370        warn_switch = value;

371        warn_strict_aliasing = value;

372 

373        /* Only warn about unknown pragmas that are not in system

374          headers.  */

375       warn_unknown_pragmas = value;

376 

377        /* We save the value of warn_uninitialized, since if they put

378          -Wuninitialized on the command line, we need to generate a

379          warning about not using it without also specifying -O.  */

380        if (warn_uninitialized != 1)

381          warn_uninitialized = (value ? 2 : 0);

382 

383        if (!c_dialect_cxx ())

384          /* We set this to 2 here, but 1 in -Wmain, so -ffreestanding

385            can turn it off only if it's not explicit.  */

386          warn_main = value * 2;

387        else

388        {

389           /* C++-specific warnings.  */

390           warn_nonvdtor = value;

391           warn_reorder = value;

392           warn_nontemplate_friend = value;

393        }

394 

395        cpp_opts->warn_trigraphs = value;

396        cpp_opts->warn_comments = value;

397        cpp_opts->warn_num_sign_change = value;

398        cpp_opts->warn_multichar = value;  /* Was C++ only.  */

399        break;

 

For –Wall switch, remember that the value at line 360 indicates if the switch is negative or not (0 for negative, 1 for otherwise, see handle_option). Here, value is 1.

 

1572 void

1573 set_Wunused (int setting)                                                                                  in opts.c

1574 {

1575   warn_unused_function = setting;

1576   warn_unused_label = setting;

1577   /* Unused function parameter warnings are reported when either

1578     ``-Wextra -Wunused'' or ``-Wunused-parameter'' is specified.

1579     Thus, if -Wextra has already been seen, set warn_unused_parameter;

1580     otherwise set maybe_warn_extra_parameter, which will be picked up

1581     by set_Wextra.  */

1582   maybe_warn_unused_parameter = setting;

1583   warn_unused_parameter = (setting && extra_warnings);

1584   warn_unused_variable = setting;

1585   warn_unused_value = setting;

1586 }

 

So in above, all flags for warning unused items are set to true. At line 1583, extra_warnings is set with switch –W/-Wextra.

 

36    void

37    set_Wformat (int setting)                                                                            in c-format.c

38    {

39      warn_format = setting;

40      warn_format_extra_args = setting;

41      warn_format_zero_length = setting;

42      if (setting != 1)

43      {

44        warn_format_nonliteral = setting;

45        warn_format_security = setting;

46        warn_format_y2k = setting;

47      }

48      /* Make sure not to disable -Wnonnull if -Wformat=0 is specified.  */

49      if (setting)

50        warn_nonnull = setting;

51    }

 

Above, warn_format (-Wformat) if nonzero, warns about format/argument anomalies in calls to formatted I/O functions (printf, scanf, strftime, strfmon, etc.).

warn_format_extra_args (C, C++, ObjC, -Wformat-extra-args) if nonzero, warns about excess arguments to formats.

warn_format_zero_length (-Wformat-zero-length) if nonzero and -Wformat is also specified, warns about zero length formats.

warn_format_nonliteral (C, C++, ObjC, -Wformat-nonliteral) if nonzero, warns about non-literal format arguments.

warn_format_security (C, C++, ObjC, -Wformat-security) if nonzero, issues a warning if -Wformat is specified and a call to a function such as printf() and scanf() presents a possible security problem. Function calls using a variable instead of a literal constant string for the formatting is not trusted because it could contain a %n.

 warn_format_y2k (C, C++, ObjC, -Wformat-y2k) if nonzero, warns about Y2K problems with strftime formats.

warn_nonnull if nonzero, warns about NULL being passed to argument slots marked as requiring non-NULL.

 

1559 static void

1560 set_Wimplicit (int on)                                                                                in c-opts.c

1561 {

1562   warn_implicit = on;

1563   warn_implicit_int = on;

1564   if (on)

1565   {

1566     if (mesg_implicit_function_declaration != 2)

1567       mesg_implicit_function_declaration = 1;

1568   }

1569   else

1570     mesg_implicit_function_declaration = 0;

1571 }

 

Above, warn_implicit if nonzero, warns about implicit declarations.

warn_implicit_int (C, -Wimplicit-int) if nonzero, warns about use of implicit int. This option is also set by -Wimplicit and -Wall.

mesg_implicit_function_declaration (C, -Wimplicit-function-declaration) if nonzero, means message about use of implicit function declarations; 1 means warning; 2 means error. This option is also set by -Wimplicit and -Wall.

Then in c_common_handle_option above, at line 363, warn_char_subscripts (C, C++, ObjC, -Wchar-subscripts) if nonzero, warns about a subscript that has type char. Because char often defaults to being signed, this can be the cause of an error.

warn_missing_braces (C, C++, ObjC, -Wmissing-braces, also set by -Wall) if nonzero, issues a warning if the initial values of an array are not completely bracketed. In the following example, both arrays a and b are initialized correctly, but braces are used for array b to be more specific about the placement of the values :

int a[2][2] = { 0, 1, 2, 3 };

int b[2][2] = { { 1, 2 }, { 3, 4} };

warn_parentheses (C, C++, ObjC, -Wparentheses, also set by -Wall) if nonzero, issues warnings for constructions that, while syntactically correct, could possibly be confusing to the programmer because of operator precedence or the structure of the code.

The following expression will cause a warning to be issued because it is difficult to remember whether logical operators associate left to right or right to left:

if(a && b || c) . . .

The following will issue a warning because, in the absence of braces, the relationships among the if and else statements could be misleading:

if(a)

if(b)

m = p;

else

a = 0;

It is apparent from the indention that the programmer intended for the else statement is to be associated with the first if statement, but it is not.

warn_return_type (C, C++, -Wreturn-type, also set by -Wall) if nonzero, warns about function definitions that default the return type or that use a null return and have a return-type other than void.

warn_sequence_point (C, -Wsequence-point, also set by -Wall) if nonzero, issues a warning if a variable is referenced more than once in an expression, and one of the references modifies its value. The definition of the C language allows expressions between sequence points to be evaluated in any order (as long as operator precedences are maintained), so modification of a variable in one location makes its value undetermined if it is used in another. A sequence point is specified in the code by the presence of one of the following operators:

; , && || ? :

The following are some examples of expressions that have ambiguous results because of a sequence point violation:

s = a[s++];

s = s--;

a[s++] = b[s];

a[s] = b[s += c];

warn_sign_compare (C, C++, ObjC, -Wsign-compare, also set by –Wall) if nonzero, warns about comparison of signed and unsigned values. If -1, neither -Wsign-compare nor -Wno-sign-compare has been specified (in which case -Wextra gets to decide).

warn_switch (C, C++, ObjC, -Wswitch, alse set by –Wall) if nonzero, warns if a switch on an enum, that does not have a default case, fails to have a case for every enum value.

warn_strict_aliasing (-Wstrict-aliasing), the strictest aliasing rules are applied depending on the language being compiled.With strict aliasing in C, for example, an int cannot be the alias of a double or a pointer, but it can be the alias of an unsigned int. Even with strict aliasing there is not a problem with union members as long as the references are through the union and not through a pointer to the address of a union member. The following code could cause a problem:

int *iptr;

union {

int ivalue;

double dvalue;

} migs;

. . .

migs.ivalue = 45;

iptr = &migs.ivalue;

frammis(*iptr);

migs.dvalue = 88.6;

frammis(*iptr);

In this example is possible that strict aliasing would not recognize that the value pointed to by iptr had changed between the two function calls. However, referring to the union members directly would not cause a problem.

warn_unknown_pragmas (-Wunknown-pragmas, also set by -Wall) if nonzero, warns about #pragma directives that are not recognized.

warn_uninitialized (-Winitialized) if nonzero, issues a warning if an automatic variable is used before it is initialized. Also issue a warning if a setjmp() call may destroy the value of an automatic variable. This option can only be used in conjunction with -O because it is the optimizing data flow information that is required for these situations to be detected.

Because this option requires data flow analysis, it is not possible for it to be completely accurate. For example, in the following code it is not possible to guarantee that value will or will not be initialized for the printf() statement:

int value;

if(a < b)

value = 5;

else if(a > c)

value = 10;

printf("%d/n",value);

Because of the nature of the data flow analysis, this option does not apply to structures, unions, arrays, any variable declared as volatile, any variable that has its address taken, or a variable used to compute a value that is never used. The data flow analysis is aware of the setjmp() statement, but it has no way of knowing from where longjmp() may be called, so a warning could be issued when there is no problem.

This option is set by -Wall if the -O option is also specified.

warn_main (C, C++, -Wmain) if nonzero, warns if main is suspicious.

warn_nonvdtor (C++, -Wnon-virtual-dtor, also set by -Wall) if nonzero, warns when declaring a class that has a non virtual destructor, when it really ought to have a virtual one.

warn_reorder (C++, -Wreorder, also set by –Wall) if nonzero, issues a warning if the compiler rearranges member initializers to match the order in which they are declared. For example, the following initializers must be rearranged:

class Reo {

int i;

int j;

Reo(): j(5), i(10) { }

};

warn_nontemplate_friend (C++, -Wnon-template-friend, also set by –Wall) if nonzero, warns when non-templatized friend functions are declared within a template.

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值