Repository: hellogcc/100-gcc-tips Branch: master Commit: f5f1f6e4433f Files: 29 Total size: 69.5 KB Directory structure: gitextract_fb7pq984/ ├── LICENSE ├── README.md ├── build.sh ├── src/ │ ├── address-sanitizer.md │ ├── cast-lose-precision.md │ ├── define-macro.md │ ├── diagnostics-color.md │ ├── index.md │ ├── inhibit-linemarkers.md │ ├── must-emit-function-code.md │ ├── must-forceinline-function-code.md │ ├── pack-struct.md │ ├── pass-options-to-assembler.md │ ├── pass-options-to-linker.md │ ├── print-commands-only.md │ ├── print-file-name.md │ ├── print-header-search-dir.md │ ├── print-level-options.md │ ├── print-predefined-macros.md │ ├── save-temps.md │ ├── set-dynamic-linker.md │ ├── specify-language.md │ ├── syntax-only.md │ ├── thread-sanitizer.md │ ├── turn-on-warnings.md │ ├── undefine-macro.md │ ├── verbose-asm.md │ └── warnings-treated-as-errors.md └── utils/ └── build.go ================================================ FILE CONTENTS ================================================ ================================================ FILE: LICENSE ================================================ GNU Free Documentation License Version 1.3, 3 November 2008 Copyright (C) 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. 0. PREAMBLE The purpose of this License is to make a manual, textbook, or other functional and useful document "free" in the sense of freedom: to assure everyone the effective freedom to copy and redistribute it, with or without modifying it, either commercially or noncommercially. Secondarily, this License preserves for the author and publisher a way to get credit for their work, while not being considered responsible for modifications made by others. This License is a kind of "copyleft", which means that derivative works of the document must themselves be free in the same sense. It complements the GNU General Public License, which is a copyleft license designed for free software. We have designed this License in order to use it for manuals for free software, because free software needs free documentation: a free program should come with manuals providing the same freedoms that the software does. But this License is not limited to software manuals; it can be used for any textual work, regardless of subject matter or whether it is published as a printed book. We recommend this License principally for works whose purpose is instruction or reference. 1. APPLICABILITY AND DEFINITIONS This License applies to any manual or other work, in any medium, that contains a notice placed by the copyright holder saying it can be distributed under the terms of this License. Such a notice grants a world-wide, royalty-free license, unlimited in duration, to use that work under the conditions stated herein. The "Document", below, refers to any such manual or work. Any member of the public is a licensee, and is addressed as "you". You accept the license if you copy, modify or distribute the work in a way requiring permission under copyright law. A "Modified Version" of the Document means any work containing the Document or a portion of it, either copied verbatim, or with modifications and/or translated into another language. A "Secondary Section" is a named appendix or a front-matter section of the Document that deals exclusively with the relationship of the publishers or authors of the Document to the Document's overall subject (or to related matters) and contains nothing that could fall directly within that overall subject. (Thus, if the Document is in part a textbook of mathematics, a Secondary Section may not explain any mathematics.) The relationship could be a matter of historical connection with the subject or with related matters, or of legal, commercial, philosophical, ethical or political position regarding them. The "Invariant Sections" are certain Secondary Sections whose titles are designated, as being those of Invariant Sections, in the notice that says that the Document is released under this License. If a section does not fit the above definition of Secondary then it is not allowed to be designated as Invariant. The Document may contain zero Invariant Sections. If the Document does not identify any Invariant Sections then there are none. The "Cover Texts" are certain short passages of text that are listed, as Front-Cover Texts or Back-Cover Texts, in the notice that says that the Document is released under this License. A Front-Cover Text may be at most 5 words, and a Back-Cover Text may be at most 25 words. A "Transparent" copy of the Document means a machine-readable copy, represented in a format whose specification is available to the general public, that is suitable for revising the document straightforwardly with generic text editors or (for images composed of pixels) generic paint programs or (for drawings) some widely available drawing editor, and that is suitable for input to text formatters or for automatic translation to a variety of formats suitable for input to text formatters. A copy made in an otherwise Transparent file format whose markup, or absence of markup, has been arranged to thwart or discourage subsequent modification by readers is not Transparent. An image format is not Transparent if used for any substantial amount of text. A copy that is not "Transparent" is called "Opaque". Examples of suitable formats for Transparent copies include plain ASCII without markup, Texinfo input format, LaTeX input format, SGML or XML using a publicly available DTD, and standard-conforming simple HTML, PostScript or PDF designed for human modification. Examples of transparent image formats include PNG, XCF and JPG. Opaque formats include proprietary formats that can be read and edited only by proprietary word processors, SGML or XML for which the DTD and/or processing tools are not generally available, and the machine-generated HTML, PostScript or PDF produced by some word processors for output purposes only. The "Title Page" means, for a printed book, the title page itself, plus such following pages as are needed to hold, legibly, the material this License requires to appear in the title page. For works in formats which do not have any title page as such, "Title Page" means the text near the most prominent appearance of the work's title, preceding the beginning of the body of the text. The "publisher" means any person or entity that distributes copies of the Document to the public. A section "Entitled XYZ" means a named subunit of the Document whose title either is precisely XYZ or contains XYZ in parentheses following text that translates XYZ in another language. (Here XYZ stands for a specific section name mentioned below, such as "Acknowledgements", "Dedications", "Endorsements", or "History".) To "Preserve the Title" of such a section when you modify the Document means that it remains a section "Entitled XYZ" according to this definition. The Document may include Warranty Disclaimers next to the notice which states that this License applies to the Document. These Warranty Disclaimers are considered to be included by reference in this License, but only as regards disclaiming warranties: any other implication that these Warranty Disclaimers may have is void and has no effect on the meaning of this License. 2. VERBATIM COPYING You may copy and distribute the Document in any medium, either commercially or noncommercially, provided that this License, the copyright notices, and the license notice saying this License applies to the Document are reproduced in all copies, and that you add no other conditions whatsoever to those of this License. You may not use technical measures to obstruct or control the reading or further copying of the copies you make or distribute. However, you may accept compensation in exchange for copies. If you distribute a large enough number of copies you must also follow the conditions in section 3. You may also lend copies, under the same conditions stated above, and you may publicly display copies. 3. COPYING IN QUANTITY If you publish printed copies (or copies in media that commonly have printed covers) of the Document, numbering more than 100, and the Document's license notice requires Cover Texts, you must enclose the copies in covers that carry, clearly and legibly, all these Cover Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on the back cover. Both covers must also clearly and legibly identify you as the publisher of these copies. The front cover must present the full title with all words of the title equally prominent and visible. You may add other material on the covers in addition. Copying with changes limited to the covers, as long as they preserve the title of the Document and satisfy these conditions, can be treated as verbatim copying in other respects. If the required texts for either cover are too voluminous to fit legibly, you should put the first ones listed (as many as fit reasonably) on the actual cover, and continue the rest onto adjacent pages. If you publish or distribute Opaque copies of the Document numbering more than 100, you must either include a machine-readable Transparent copy along with each Opaque copy, or state in or with each Opaque copy a computer-network location from which the general network-using public has access to download using public-standard network protocols a complete Transparent copy of the Document, free of added material. If you use the latter option, you must take reasonably prudent steps, when you begin distribution of Opaque copies in quantity, to ensure that this Transparent copy will remain thus accessible at the stated location until at least one year after the last time you distribute an Opaque copy (directly or through your agents or retailers) of that edition to the public. It is requested, but not required, that you contact the authors of the Document well before redistributing any large number of copies, to give them a chance to provide you with an updated version of the Document. 4. MODIFICATIONS You may copy and distribute a Modified Version of the Document under the conditions of sections 2 and 3 above, provided that you release the Modified Version under precisely this License, with the Modified Version filling the role of the Document, thus licensing distribution and modification of the Modified Version to whoever possesses a copy of it. In addition, you must do these things in the Modified Version: A. Use in the Title Page (and on the covers, if any) a title distinct from that of the Document, and from those of previous versions (which should, if there were any, be listed in the History section of the Document). You may use the same title as a previous version if the original publisher of that version gives permission. B. List on the Title Page, as authors, one or more persons or entities responsible for authorship of the modifications in the Modified Version, together with at least five of the principal authors of the Document (all of its principal authors, if it has fewer than five), unless they release you from this requirement. C. State on the Title page the name of the publisher of the Modified Version, as the publisher. D. Preserve all the copyright notices of the Document. E. Add an appropriate copyright notice for your modifications adjacent to the other copyright notices. F. Include, immediately after the copyright notices, a license notice giving the public permission to use the Modified Version under the terms of this License, in the form shown in the Addendum below. G. Preserve in that license notice the full lists of Invariant Sections and required Cover Texts given in the Document's license notice. H. Include an unaltered copy of this License. I. Preserve the section Entitled "History", Preserve its Title, and add to it an item stating at least the title, year, new authors, and publisher of the Modified Version as given on the Title Page. If there is no section Entitled "History" in the Document, create one stating the title, year, authors, and publisher of the Document as given on its Title Page, then add an item describing the Modified Version as stated in the previous sentence. J. Preserve the network location, if any, given in the Document for public access to a Transparent copy of the Document, and likewise the network locations given in the Document for previous versions it was based on. These may be placed in the "History" section. You may omit a network location for a work that was published at least four years before the Document itself, or if the original publisher of the version it refers to gives permission. K. For any section Entitled "Acknowledgements" or "Dedications", Preserve the Title of the section, and preserve in the section all the substance and tone of each of the contributor acknowledgements and/or dedications given therein. L. Preserve all the Invariant Sections of the Document, unaltered in their text and in their titles. Section numbers or the equivalent are not considered part of the section titles. M. Delete any section Entitled "Endorsements". Such a section may not be included in the Modified Version. N. Do not retitle any existing section to be Entitled "Endorsements" or to conflict in title with any Invariant Section. O. Preserve any Warranty Disclaimers. If the Modified Version includes new front-matter sections or appendices that qualify as Secondary Sections and contain no material copied from the Document, you may at your option designate some or all of these sections as invariant. To do this, add their titles to the list of Invariant Sections in the Modified Version's license notice. These titles must be distinct from any other section titles. You may add a section Entitled "Endorsements", provided it contains nothing but endorsements of your Modified Version by various parties--for example, statements of peer review or that the text has been approved by an organization as the authoritative definition of a standard. You may add a passage of up to five words as a Front-Cover Text, and a passage of up to 25 words as a Back-Cover Text, to the end of the list of Cover Texts in the Modified Version. Only one passage of Front-Cover Text and one of Back-Cover Text may be added by (or through arrangements made by) any one entity. If the Document already includes a cover text for the same cover, previously added by you or by arrangement made by the same entity you are acting on behalf of, you may not add another; but you may replace the old one, on explicit permission from the previous publisher that added the old one. The author(s) and publisher(s) of the Document do not by this License give permission to use their names for publicity for or to assert or imply endorsement of any Modified Version. 5. COMBINING DOCUMENTS You may combine the Document with other documents released under this License, under the terms defined in section 4 above for modified versions, provided that you include in the combination all of the Invariant Sections of all of the original documents, unmodified, and list them all as Invariant Sections of your combined work in its license notice, and that you preserve all their Warranty Disclaimers. The combined work need only contain one copy of this License, and multiple identical Invariant Sections may be replaced with a single copy. If there are multiple Invariant Sections with the same name but different contents, make the title of each such section unique by adding at the end of it, in parentheses, the name of the original author or publisher of that section if known, or else a unique number. Make the same adjustment to the section titles in the list of Invariant Sections in the license notice of the combined work. In the combination, you must combine any sections Entitled "History" in the various original documents, forming one section Entitled "History"; likewise combine any sections Entitled "Acknowledgements", and any sections Entitled "Dedications". You must delete all sections Entitled "Endorsements". 6. COLLECTIONS OF DOCUMENTS You may make a collection consisting of the Document and other documents released under this License, and replace the individual copies of this License in the various documents with a single copy that is included in the collection, provided that you follow the rules of this License for verbatim copying of each of the documents in all other respects. You may extract a single document from such a collection, and distribute it individually under this License, provided you insert a copy of this License into the extracted document, and follow this License in all other respects regarding verbatim copying of that document. 7. AGGREGATION WITH INDEPENDENT WORKS A compilation of the Document or its derivatives with other separate and independent documents or works, in or on a volume of a storage or distribution medium, is called an "aggregate" if the copyright resulting from the compilation is not used to limit the legal rights of the compilation's users beyond what the individual works permit. When the Document is included in an aggregate, this License does not apply to the other works in the aggregate which are not themselves derivative works of the Document. If the Cover Text requirement of section 3 is applicable to these copies of the Document, then if the Document is less than one half of the entire aggregate, the Document's Cover Texts may be placed on covers that bracket the Document within the aggregate, or the electronic equivalent of covers if the Document is in electronic form. Otherwise they must appear on printed covers that bracket the whole aggregate. 8. TRANSLATION Translation is considered a kind of modification, so you may distribute translations of the Document under the terms of section 4. Replacing Invariant Sections with translations requires special permission from their copyright holders, but you may include translations of some or all Invariant Sections in addition to the original versions of these Invariant Sections. You may include a translation of this License, and all the license notices in the Document, and any Warranty Disclaimers, provided that you also include the original English version of this License and the original versions of those notices and disclaimers. In case of a disagreement between the translation and the original version of this License or a notice or disclaimer, the original version will prevail. If a section in the Document is Entitled "Acknowledgements", "Dedications", or "History", the requirement (section 4) to Preserve its Title (section 1) will typically require changing the actual title. 9. TERMINATION You may not copy, modify, sublicense, or distribute the Document except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, or distribute it is void, and will automatically terminate your rights under this License. However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, receipt of a copy of some or all of the same material does not give you any rights to use it. 10. FUTURE REVISIONS OF THIS LICENSE The Free Software Foundation may publish new, revised versions of the GNU Free Documentation License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. See http://www.gnu.org/copyleft/. Each version of the License is given a distinguishing version number. If the Document specifies that a particular numbered version of this License "or any later version" applies to it, you have the option of following the terms and conditions either of that specified version or of any later version that has been published (not as a draft) by the Free Software Foundation. If the Document does not specify a version number of this License, you may choose any version ever published (not as a draft) by the Free Software Foundation. If the Document specifies that a proxy can decide which future versions of this License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Document. 11. RELICENSING "Massive Multiauthor Collaboration Site" (or "MMC Site") means any World Wide Web server that publishes copyrightable works and also provides prominent facilities for anybody to edit those works. A public wiki that anybody can edit is an example of such a server. A "Massive Multiauthor Collaboration" (or "MMC") contained in the site means any set of copyrightable works thus published on the MMC site. "CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0 license published by Creative Commons Corporation, a not-for-profit corporation with a principal place of business in San Francisco, California, as well as future copyleft versions of that license published by that same organization. "Incorporate" means to publish or republish a Document, in whole or in part, as part of another Document. An MMC is "eligible for relicensing" if it is licensed under this License, and if all works that were first published under this License somewhere other than this MMC, and subsequently incorporated in whole or in part into the MMC, (1) had no cover texts or invariant sections, and (2) were thus incorporated prior to November 1, 2008. The operator of an MMC Site may republish an MMC contained in the site under CC-BY-SA on the same site at any time before August 1, 2009, provided the MMC is eligible for relicensing. ADDENDUM: How to use this License for your documents To use this License in a document you have written, include a copy of the License in the document and put the following copyright and license notices just after the title page: Copyright (c) YEAR YOUR NAME. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License". If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, replace the "with...Texts." line with this: with the Invariant Sections being LIST THEIR TITLES, with the Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST. If you have Invariant Sections without Cover Texts, or some other combination of the three, merge those two alternatives to suit the situation. If your document contains nontrivial examples of program code, we recommend releasing these examples in parallel under your choice of free software license, such as the GNU General Public License, to permit their use in free software. ================================================ FILE: README.md ================================================ # 《100个gcc小技巧》 一个关于gcc使用小技巧的文档。100,在这里可能只是表明很多;具体的数目取决于您的参与和贡献。 ## 在线阅读 [开始阅读]() ## 如何参与 直接发PULL REQUEST,或与我们联系。 增加一个小技巧的步骤: 1. 在src目录下新增一个md文件,参照现有文件的格式风格,编写一个小技巧 markdown语法参见 http://wowubuntu.com/markdown/ md文件编写可以使用在线所见即所得编辑器 https://www.zybuluo.com/mdeditor 2. 在index.md中为新md文件增加一个索引,可以放到已有分类中,或增加一个分类 3. 如果预览下没有问题,OK! 本地生成html的步骤: 1. 确保[go](http://code.google.com/p/go)和[md2min](https://github.com/fairlyblank/md2min)已经安装并可用 2. 直接运行build.sh 3. 如果顺利,会在html目录下生成所有的html文件 ## 联系方式 - [博客网站](http://www.hellogcc.org) - 在线讨论问题:IRC, freenode, #hellogcc房间 - [邮件列表](http://www.freelists.org/list/hellogcc) (发信需要先订阅) ## 版权 本文档版权归贡献者所有。 ## 授权许可 本文档使用的是[GNU Free Documentation License](http://www.gnu.org/licenses/fdl.html)。 ## 致谢 - 各位参与者 ## 其它资源 - [GCC在线手册](https://gcc.gnu.org/onlinedocs/gcc) ================================================ FILE: build.sh ================================================ #!/bin/sh # This script invokes md2min to convert markdown files to minimal html files, # using github css. So go and md2min should be available before you run it. # See https://github.com/fairlyblank/md2min # See http://code.google.com/p/go TOPDIR=`dirname $0` if [ ! type -P go >/dev/null 2>&1 ]; then echo "error: can't find go, which is necessary for building html" exit 0 fi if [ ! type -P md2min >/dev/null 2>&1 ]; then echo "error: can't find md2min, which is necessary for building html" exit 0 fi mkdir -p "$TOPDIR/html" ( export SRC="$TOPDIR/src" export HTML="$TOPDIR/html" go run "$TOPDIR/utils/build.go" ) ================================================ FILE: src/address-sanitizer.md ================================================ # 利用Address Sanitizer工具检查内存访问错误 ## 例子 a.c: #include int main(void) { // your code goes here int a[3] = {0}; a[3] = 1; printf("%d\n", a[3]); return 0; } b.c: #include #include int main(void) { int *p = NULL; p = malloc(10 * sizeof(int)); free(p); *p = 3; return 0; } ## 技巧 gcc从`4.8`版本起,集成了`Address Sanitizer`工具,可以用来检查内存访问的错误(编译时指定“`-fsanitize=address`”)。以上面`a.c`程序为例: gcc -fsanitize=address -g -o a a.c 执行`a`程序: [root@localhost nan]# ./a ================================================================= ==539==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fff3a152c9c at pc 0x4009b6 bp 0x7fff3a152c60 sp 0x7fff3a152c58 WRITE of size 4 at 0x7fff3a152c9c thread T0 #0 0x4009b5 in main /home/nan/a.c:6 #1 0x34e421ed1c in __libc_start_main (/lib64/libc.so.6+0x34e421ed1c) #2 0x4007b8 (/home/nan/a+0x4007b8) Address 0x7fff3a152c9c is located in stack of thread T0 at offset 44 in frame #0 0x400907 in main /home/nan/a.c:3 This frame has 1 object(s): [32, 44) 'a' <== Memory access at offset 44 overflows this variable HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext (longjmp and C++ exceptions *are* supported) SUMMARY: AddressSanitizer: stack-buffer-overflow /home/nan/a.c:6 main Shadow bytes around the buggy address: 0x100067422540: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x100067422550: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x100067422560: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x100067422570: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x100067422580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 =>0x100067422590: f1 f1 00[04]f4 f4 f3 f3 f3 f3 00 00 00 00 00 00 0x1000674225a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x1000674225b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x1000674225c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x1000674225d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x1000674225e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Heap right redzone: fb Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack partial redzone: f4 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Contiguous container OOB:fc ASan internal: fe ==539==ABORTING 可以看到,执行程序时检测出了`a`数组的越界访问(`a[3] = 1`)。 再看一下`b`程序: gcc -fsanitize=address -g -o b b.c 执行`b`程序: [root@localhost nan]# ./b ================================================================= ==1951==ERROR: AddressSanitizer: heap-use-after-free on address 0x60400000dfd0 at pc 0x4007f9 bp 0x7fff34277bb0 sp 0x7fff34277ba8 WRITE of size 4 at 0x60400000dfd0 thread T0 #0 0x4007f8 in main /home/nan/b.c:9 #1 0x34e421ed1c in __libc_start_main (/lib64/libc.so.6+0x34e421ed1c) #2 0x400658 (/home/nan/b+0x400658) 0x60400000dfd0 is located 0 bytes inside of 40-byte region [0x60400000dfd0,0x60400000dff8) freed by thread T0 here: #0 0x7fbbb7a7d057 in __interceptor_free /opt/gcc-4.9.2/src/gcc-4.9.2/libsanitizer/asan/asan_malloc_linux.cc:62 #1 0x4007c1 in main /home/nan/b.c:8 #2 0x34e421ed1c in __libc_start_main (/lib64/libc.so.6+0x34e421ed1c) previously allocated by thread T0 here: #0 0x7fbbb7a7d26f in __interceptor_malloc /opt/gcc-4.9.2/src/gcc-4.9.2/libsanitizer/asan/asan_malloc_linux.cc:72 #1 0x4007b1 in main /home/nan/b.c:7 #2 0x34e421ed1c in __libc_start_main (/lib64/libc.so.6+0x34e421ed1c) SUMMARY: AddressSanitizer: heap-use-after-free /home/nan/b.c:9 main Shadow bytes around the buggy address: 0x0c087fff9ba0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c087fff9bb0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c087fff9bc0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c087fff9bd0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c087fff9be0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa =>0x0c087fff9bf0: fa fa fa fa fa fa fa fa fa fa[fd]fd fd fd fd fa 0x0c087fff9c00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c087fff9c10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c087fff9c20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c087fff9c30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c087fff9c40: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Heap right redzone: fb Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack partial redzone: f4 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Contiguous container OOB:fc ASan internal: fe ==1951==ABORTING 执行程序时检测出了访问释放内存的错误(`*p = 3`)。 详情参见[gcc手册](https://gcc.gnu.org/onlinedocs/gcc-4.9.2/gcc/Debugging-Options.html#index-fsanitize_003daddress-593) ## 贡献者 nanxiao ================================================ FILE: src/cast-lose-precision.md ================================================ # error: cast from ... to ... loses precision ## 例子 #include class Foo { public: void print() const { std::cout << (int)(this) << "\n"; } }; int main() { class Foo foo; foo.print(); return 0; } ## 技巧 在g++编译上面的例子,会报如下错误: $ g++ foo.cc foo.cc: In member function ‘void Foo::print() const’: foo.cc:6:28: error: cast from ‘const Foo*’ to ‘int’ loses precision [-fpermissive] 这是一个强制类型转换的错误,你可以修改源代码为: std::cout << (int*)(this) << "\n"; 即可。 如果,你不想(或不能)去修改源程序,只是应为升级了gcc而带来了这样的错误,那么也可以使用`-fpermissive`选项,将错误降低为警告: $ g++ foo.cc -fpermissive foo.cc: In member function ‘void Foo::print() const’: foo.cc:6:28: warning: cast from ‘const Foo*’ to ‘int’ loses precision [-fpermissive] 详情参见[gcc手册](https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Dialect-Options.html#index-fpermissive-166) ## 贡献者 xmj ================================================ FILE: src/define-macro.md ================================================ # 在命令行中预定义宏 ## 例子 #include int main (void) { int i, sum; for (i = 1, sum = 0; i <= 10; i++) { sum += i; #ifdef DEBUG printf ("sum += %d is %d\n", i, sum); #endif } printf ("total sum is %d\n", sum); return 0; } ## 技巧 使用`-D`选项可以在命令行中预定义一个宏,比如: $ gcc -D DEBUG macro.c 中间可以没有空格: $ gcc -DDEBUG macro.c 详情参见[gcc手册](https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html#Preprocessor-Options) ## 贡献者 xmj ================================================ FILE: src/diagnostics-color.md ================================================ # 打印彩色诊断信息 ## 技巧 这是gcc-4.9新增的功能,可以通过定义环境变量`GCC_COLORS`来彩色打印诊断信息。 也可以使用选项`-fdiagnostics-color`来设定。 详情参见[gcc手册](https://gcc.gnu.org/onlinedocs/gcc/Language-Independent-Options.html#Language-Independent-Options) ## 贡献者 xmj ================================================ FILE: src/index.md ================================================ # 信息显示 * [打印gcc预定义的宏信息](print-predefined-macros.md) * [打印gcc执行的子命令](print-commands-only.md) * [打印优化级别的对应选项](print-level-options.md) * [打印彩色诊断信息](diagnostics-color.md) * [打印头文件搜索路径](print-header-search-dir.md) * [打印连接库的具体路径](print-file-name.md) # 预处理 * [生成没有行号标记的预处理文件](inhibit-linemarkers.md) * [在命令行中预定义宏](define-macro.md) * [在命令行中取消宏定义](undefine-macro.md) # 汇编 * [把选项传给汇编器](pass-options-to-assembler.md) * [生成有详细信息的汇编文件](verbose-asm.md) # 调试 * [利用Address Sanitizer工具检查内存访问错误](address-sanitizer.md) * [利用Thread Sanitizer工具检查数据竞争的问题](thread-sanitizer.md) # 连接 * [把选项传给连接器](pass-options-to-linker.md) * [设置动态连接器](set-dynamic-linker.md) # 函数属性 * [禁止函数被优化掉](must-emit-function-code.md) * [强制函数inline](must-forceinline-function-code.md) # 常见错误 * [error: cast from ... to ... loses precision](cast-lose-precision.md) * [all warnings being treated as errors](warnings-treated-as-errors.md) * [gdb无法调试gcc编译的程序](specify-dwarf-version.md) # 其它 * [只做语法检查](syntax-only.md) * [保存临时文件](save-temps.md) * [打开警告信息](turn-on-warnings.md) * [指定语言类型](specify-language.md) * [改变结构体成员的字节对齐](pack-struct.md) ================================================ FILE: src/inhibit-linemarkers.md ================================================ # 生成没有行号标记的预处理文件 ## 技巧 有时编译程序会遇到如下类似的错误, In file included from foo.c:15, from a.h:45, b.h:53: error: ... ... 如果错误是由于你所定义的一个很复杂的宏所引起的,你可能会需要先手动编译生成相应的预处理文件,查看下预处理文件中的宏扩展代码。比如,先运行 gcc -E foo.c -o foo.i 来生成foo.i预处理文件。然后,还可以尝试手动修改、编译这个预处理文件。 但是,由于生成的预处理文件中含有行号标记(linemarker),所以,运行 gcc -c foo.i -o foo.o 所得到的错误行号信息还是跟最初的一样,如果可以将预处理文件中的行号标记都去掉,似乎会有些帮助。 幸好,gcc提供了这个选项: > -P > Inhibit generation of linemarkers in the output from the > preprocessor. This might be useful when running the preprocessor on > something that is not C code, and will be sent to a program which > might be confused by the linemarkers. 运行 gcc -E -P foo.c -o foo.i 即可。 详情参见[gcc手册](https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html#Preprocessor-Options) ## 贡献者 xmj ================================================ FILE: src/must-emit-function-code.md ================================================ # 禁止函数被优化掉 ## 例子 #if (GCC_VERSION > 4000) #define DEBUG_FUNCTION __attribute__ ((__used__)) #define DEBUG_VARIABLE __attribute__ ((__used__)) #else #define DEBUG_FUNCTION #define DEBUG_VARIABLE #endif DEBUG_FUNCTION void debug_bb (basic_block bb) { dump_bb (bb, stderr, 0); } ## 技巧 上面的例子是gcc的源码。使用gcc的扩展功能——函数属性`__attribute__ ((__used__))`,可以指定该函数是有用的,不能被优化掉。 详情参见[gcc手册](https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html#Function-Attributes) ## 贡献者 xmj ================================================ FILE: src/must-forceinline-function-code.md ================================================ # 强制函数永远以inline的形式调用 ## 例子 #if defined(__GNUC__) #define FORCEDINLINE __attribute__((always_inline)) #else #define FORCEDINLINE #endif FORCEDINLINE int add(int a,int b) { return a+b; } ## 技巧 上面的例子是gcc的源码。使用gcc的扩展功能——函数属性`__attribute__ ((always_inline))`,可以指定该函数永远以inline的形式调用 详情参见[gcc手册](https://gcc.gnu.org/onlinedocs/gcc/Inline.html) ## 贡献者 mengke ================================================ FILE: src/pack-struct.md ================================================ # 改变结构体成员的字节对齐 ## 例子 #include typedef struct { char a; int b; } ST_A; int main(void) { printf("sizeof(ST_A)=%ld\n",sizeof(ST_A)); } ## 技巧 在上面的程序里,`ST_A`结构体的内存布局默认是这样的:
Offset 1byte 1byte 1byte 1byte
0 a 填充字节 填充字节 填充字节
4 b b b b
编译执行,结果如下: root@ubuntu:~$ gcc -g -o a a.c root@ubuntu:~$ ./a sizeof(ST_A)=8 使用gcc的"`-fpack-struct[=n]`"选项(“`n`”需要为`2`的倍数)可以改变成员的地址对齐。例如指定“`n=2`”时,将标明结构体成员的最大对齐地址为2。这样`ST_A`结构体中的成员`b`的地址将不再按照`4`字节对齐,内存布局变为:
Offset 1byte 1byte 1byte 1byte
0 a 填充字节 b b
4 b b
编译执行,结果如下: root@ubuntu:~$ gcc -g -fpack-struct=2 -o a a.c root@ubuntu:~$ ./a sizeof(ST_A)=6 当不指定“`n`”时,将没有填充字节,所有成员将一个挨着一个排在一起:
Offset 1byte 1byte 1byte 1byte
0 a b b b
4 b
编译执行,结果如下: root@ubuntu:~$ gcc -g -fpack-struct -o a a.c root@ubuntu:~$ ./a sizeof(ST_A)=5 由于这个编译选项会导致ABI(Application Binary Interface)的改变,所以使用时一定要谨慎。 详情参见[gcc手册](https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html) ## 贡献者 nanxiao ================================================ FILE: src/pass-options-to-assembler.md ================================================ # 把选项传给汇编器 ## 例子 #include int main(void) { int i; for (i = 0; i < 10; i++) printf("%d ", i); putchar ('\n'); return 0; } ## 技巧 使用`-Wa,option`可以将选项`option`传递给汇编器。 注意,逗号和选项之间不能有空格。例如: $ gcc -c -Wa,-L foo.c $ objdump -d foo.o foo.o: file format elf64-x86-64 Disassembly of section .text: 0000000000000000
: 0: 55 push %rbp 1: 48 89 e5 mov %rsp,%rbp 4: 48 83 ec 10 sub $0x10,%rsp 8: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%rbp) f: eb 1b jmp 2c <.L2> 0000000000000011 <.L3>: 11: b8 00 00 00 00 mov $0x0,%eax 16: 8b 55 fc mov -0x4(%rbp),%edx 19: 89 d6 mov %edx,%esi 1b: 48 89 c7 mov %rax,%rdi 1e: b8 00 00 00 00 mov $0x0,%eax 23: e8 00 00 00 00 callq 28 <.L3+0x17> 28: 83 45 fc 01 addl $0x1,-0x4(%rbp) 000000000000002c <.L2>: 2c: 83 7d fc 09 cmpl $0x9,-0x4(%rbp) 30: 7e df jle 11 <.L3> 32: bf 0a 00 00 00 mov $0xa,%edi 37: e8 00 00 00 00 callq 3c <.L2+0x10> 3c: b8 00 00 00 00 mov $0x0,%eax 41: c9 leaveq 42: c3 retq 这里的`-L`是汇编器as的选项,用于在目标文件中保留局部符号(local symbol)。可以看到,反汇编代码中给出了每个局部符号。 如果此时你使用`oprofile`来统计性能事件,那么获得的结果将不是以函数为单位了,而是以这些符号所划分的代码块为单位。 详情参见[gcc手册](https://gcc.gnu.org/onlinedocs/gcc/Assembler-Options.html#Assembler-Options)和[as手册](https://sourceware.org/binutils/docs-2.24/as/L.html#L) ## 贡献者 xmj ================================================ FILE: src/pass-options-to-linker.md ================================================ # 把选项传给连接器 ## 例子 #include int main (void) { puts ("Hello world!"); return 0; } ## 技巧 使用`-Wl,option`可以将选项`option`传递给连接器。 注意,逗号和选项之间不能有空格。一种常见用法,就是让连接器生成内存映射文件,例如: $ gcc -Wl,-Map=output.map foo.c $ cat output.map Archive member included because of file (symbol) /usr/lib/x86_64-linux-gnu/libc_nonshared.a(elf-init.oS) /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crt1.o (__libc_csu_init) Discarded input sections .note.GNU-stack 0x0000000000000000 0x0 /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crt1.o .gnu_debuglink 0x0000000000000000 0xc /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crt1.o .note.GNU-stack 0x0000000000000000 0x0 /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crti.o .gnu_debuglink 0x0000000000000000 0xc /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crti.o .note.GNU-stack 0x0000000000000000 0x0 /usr/lib/gcc/x86_64-linux-gnu/4.6/crtbegin.o .note.GNU-stack 0x0000000000000000 0x0 /tmp/ccBOhdmq.o .note.GNU-stack 0x0000000000000000 0x0 /usr/lib/x86_64-linux-gnu/libc_nonshared.a(elf-init.oS) .note.GNU-stack 0x0000000000000000 0x0 /usr/lib/gcc/x86_64-linux-gnu/4.6/crtend.o .note.GNU-stack 0x0000000000000000 0x0 /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crtn.o .gnu_debuglink 0x0000000000000000 0xc /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crtn.o Memory map ** file header 0x0000000000400000 0x40 ** segment headers 0x0000000000400040 0x1f8 .interp 0x0000000000400238 0x1c ** fill 0x0000000000400238 0x1c .note.ABI-tag 0x0000000000400254 0x20 .note.ABI-tag 0x0000000000400254 0x20 /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crt1.o .note.gnu.build-id 0x0000000000400274 0x24 ** note header 0x0000000000400274 0x10 ** zero fill 0x0000000000400284 0x14 .dynsym 0x0000000000400298 0x78 ** dynsym 0x0000000000400298 0x78 .dynstr 0x0000000000400310 0x51 ** string table 0x0000000000400310 0x51 .gnu.hash 0x0000000000400368 0x1c ** hash 0x0000000000400368 0x1c .gnu.version 0x0000000000400384 0xa ** versions 0x0000000000400384 0xa .gnu.version_r 0x0000000000400390 0x20 ** version refs 0x0000000000400390 0x20 .rela.dyn 0x00000000004003b0 0x18 ** dynamic relocs 0x00000000004003b0 0x18 .rela.plt 0x00000000004003c8 0x30 ** dynamic relocs 0x00000000004003c8 0x30 .init 0x00000000004003f8 0x18 .init 0x00000000004003f8 0x9 /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crti.o 0x00000000004003f8 _init .init 0x0000000000400401 0x5 /usr/lib/gcc/x86_64-linux-gnu/4.6/crtbegin.o .init 0x0000000000400406 0x5 /usr/lib/gcc/x86_64-linux-gnu/4.6/crtend.o .init 0x000000000040040b 0x5 /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crtn.o .plt 0x0000000000400410 0x30 ** PLT 0x0000000000400410 0x30 .text 0x0000000000400440 0x1d8 .text 0x0000000000400440 0x2c /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crt1.o 0x0000000000400440 _start .text 0x000000000040046c 0x17 /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crti.o ** fill 0x0000000000400483 0xd .text 0x0000000000400490 0x92 /usr/lib/gcc/x86_64-linux-gnu/4.6/crtbegin.o .text 0x0000000000400522 0x15 /tmp/ccBOhdmq.o 0x0000000000400522 main ** fill 0x0000000000400537 0x9 .text 0x0000000000400540 0x92 /usr/lib/x86_64-linux-gnu/libc_nonshared.a(elf-init.oS) 0x0000000000400540 __libc_csu_init 0x00000000004005d0 __libc_csu_fini ** fill 0x00000000004005d2 0xe .text 0x00000000004005e0 0x36 /usr/lib/gcc/x86_64-linux-gnu/4.6/crtend.o ** fill 0x0000000000400616 0x2 .text 0x0000000000400618 0x0 /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crtn.o .fini 0x0000000000400618 0xe .fini 0x0000000000400618 0x4 /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crti.o 0x0000000000400618 _fini .fini 0x000000000040061c 0x5 /usr/lib/gcc/x86_64-linux-gnu/4.6/crtbegin.o .fini 0x0000000000400621 0x5 /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crtn.o .rodata 0x0000000000400628 0x11 ** merge constants 0x0000000000400628 0x4 .rodata 0x000000000040062c 0xd /tmp/ccBOhdmq.o .eh_frame 0x0000000000400640 0xa4 ** eh_frame 0x0000000000400640 0xa0 .eh_frame 0x00000000004006e0 0x4 /usr/lib/gcc/x86_64-linux-gnu/4.6/crtend.o .eh_frame_hdr 0x00000000004006e4 0x2c ** eh_frame_hdr 0x00000000004006e4 0x2c .ctors 0x0000000000401e28 0x10 .ctors 0x0000000000401e28 0x8 /usr/lib/gcc/x86_64-linux-gnu/4.6/crtbegin.o .ctors 0x0000000000401e30 0x8 /usr/lib/gcc/x86_64-linux-gnu/4.6/crtend.o .dtors 0x0000000000401e38 0x10 .dtors 0x0000000000401e38 0x8 /usr/lib/gcc/x86_64-linux-gnu/4.6/crtbegin.o .dtors 0x0000000000401e40 0x8 /usr/lib/gcc/x86_64-linux-gnu/4.6/crtend.o 0x0000000000401e40 __DTOR_END__ .jcr 0x0000000000401e48 0x8 .jcr 0x0000000000401e48 0x0 /usr/lib/gcc/x86_64-linux-gnu/4.6/crtbegin.o .jcr 0x0000000000401e48 0x8 /usr/lib/gcc/x86_64-linux-gnu/4.6/crtend.o .dynamic 0x0000000000401e50 0x190 ** dynamic 0x0000000000401e50 0x190 .got 0x0000000000401fe0 0x8 ** GOT 0x0000000000401fe0 0x8 .got.plt 0x0000000000401fe8 0x28 ** GOT PLT 0x0000000000401fe8 0x28 ** GOT IRELATIVE PLT 0x0000000000402010 0x0 ** GOT 0x0000000000402010 0x0 .data 0x0000000000402010 0x10 .data 0x0000000000402010 0x4 /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crt1.o 0x0000000000402010 data_start 0x0000000000402010 __data_start .data 0x0000000000402014 0x0 /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crti.o .data 0x0000000000402018 0x8 /usr/lib/gcc/x86_64-linux-gnu/4.6/crtbegin.o 0x0000000000402018 __dso_handle .data 0x0000000000402020 0x0 /tmp/ccBOhdmq.o .data 0x0000000000402020 0x0 /usr/lib/x86_64-linux-gnu/libc_nonshared.a(elf-init.oS) .data 0x0000000000402020 0x0 /usr/lib/gcc/x86_64-linux-gnu/4.6/crtend.o .data 0x0000000000402020 0x0 /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crtn.o .bss 0x0000000000402020 0x10 .bss 0x0000000000402020 0x0 /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crt1.o .bss 0x0000000000402020 0x0 /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crti.o .bss 0x0000000000402020 0x10 /usr/lib/gcc/x86_64-linux-gnu/4.6/crtbegin.o .bss 0x0000000000402030 0x0 /tmp/ccBOhdmq.o .bss 0x0000000000402030 0x0 /usr/lib/x86_64-linux-gnu/libc_nonshared.a(elf-init.oS) .bss 0x0000000000402030 0x0 /usr/lib/gcc/x86_64-linux-gnu/4.6/crtend.o .bss 0x0000000000402030 0x0 /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crtn.o .comment 0x0000000000000000 0x2b ** merge strings 0x0000000000000000 0x2b .note.gnu.gold-version 0x0000000000000000 0x1c ** note header 0x0000000000000000 0x10 ** fill 0x0000000000000010 0x9 ** zero fill 0x0000000000000019 0x3 .symtab 0x0000000000000000 0x390 ** symtab 0x0000000000000000 0x390 .strtab 0x0000000000000000 0x1d5 ** string table 0x0000000000000000 0x1d5 .shstrtab 0x0000000000000000 0x115 ** string table 0x0000000000000000 0x115 详情参见[gcc手册](https://gcc.gnu.org/onlinedocs/gcc/Link-Options.html#Link-Options) ## 贡献者 xmj ================================================ FILE: src/print-commands-only.md ================================================ # 打印gcc执行的子命令 ## 例子 $ gcc -### foo.c Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.6/lto-wrapper Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.6.3-1ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu Thread model: posix gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) COLLECT_GCC_OPTIONS='-mtune=generic' '-march=x86-64' /usr/lib/gcc/x86_64-linux-gnu/4.6/cc1 -quiet -imultilib . -imultiarch x86_64-linux-gnu foo.c -quiet -dumpbase foo.c "-mtune=generic" "-march=x86-64" -auxbase foo -fstack-protector -o /tmp/ccezMraJ.s COLLECT_GCC_OPTIONS='-mtune=generic' '-march=x86-64' as --64 -o /tmp/cc9Ce7IE.o /tmp/ccezMraJ.s COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/4.6/:/usr/lib/gcc/x86_64-linux-gnu/4.6/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/4.6/:/usr/lib/gcc/x86_64-linux-gnu/ LIBRARY_PATH=/home/xmj/install/cap-llvm-3.4/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/4.6/:/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/home/xmj/install/cap-llvm-3.4/lib/:/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../:/lib/:/usr/lib/ COLLECT_GCC_OPTIONS='-mtune=generic' '-march=x86-64' /usr/lib/gcc/x86_64-linux-gnu/4.6/collect2 "--sysroot=/" --build-id --no-add-needed --as-needed --eh-frame-hdr -m elf_x86_64 "--hash-style=gnu" -dynamic-linker /lib64/ld-linux-x86-64.so.2 -z relro /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crt1.o /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.6/crtbegin.o -L/home/xmj/install/cap-llvm-3.4/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/4.6 -L/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/home/xmj/install/cap-llvm-3.4/lib -L/usr/lib/gcc/x86_64-linux-gnu/4.6/../../.. /tmp/cc9Ce7IE.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-linux-gnu/4.6/crtend.o /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crtn.o ## 技巧 如上所示,使用`-###`选项可以打印出gcc所执行的各个子命令,分别为, cc1: /usr/lib/gcc/x86_64-linux-gnu/4.6/cc1 -quiet -imultilib . -imultiarch x86_64-linux-gnu foo.c -quiet -dumpbase foo.c "-mtune=generic" "-march=x86-64" -auxbase foo -fstack-protector -o /tmp/ccezMraJ.s as: as --64 -o /tmp/cc9Ce7IE.o /tmp/ccezMraJ.s collect2: /usr/lib/gcc/x86_64-linux-gnu/4.6/collect2 "--sysroot=/" --build-id --no-add-needed --as-needed --eh-frame-hdr -m elf_x86_64 "--hash-style=gnu" -dynamic-linker /lib64/ld-linux-x86-64.so.2 -z relro /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crt1.o /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.6/crtbegin.o -L/home/xmj/install/cap-llvm-3.4/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/4.6 -L/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/home/xmj/install/cap-llvm-3.4/lib -L/usr/lib/gcc/x86_64-linux-gnu/4.6/../../.. /tmp/cc9Ce7IE.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-linux-gnu/4.6/crtend.o /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crtn.o 这个跟使用`-v`所显示的内容差不多,区别在于使用`-###`是只打印,不实际执行具体的命令。手册里提到,它的一种用法,就是在脚本里使用这个选项,来获得gcc所调用的各个子命令行。 详情参见[gcc手册](https://gcc.gnu.org/onlinedocs/gcc/Overall-Options.html#Overall-Options) ## 贡献者 xmj ================================================ FILE: src/print-file-name.md ================================================ # 打印连接库的具体路径 ## 例子 $ gcc -print-file-name=libc.a /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/libc.a ## 技巧 如上所示,使用`-print-file-name`选项就可以显示出gcc究竟会连接哪个libc库了。 详情参见[gcc手册](https://gcc.gnu.org/onlinedocs/gcc/Developer-Options.html#index-print-file-name) ## 贡献者 xmj ================================================ FILE: src/print-header-search-dir.md ================================================ # 打印头文件搜索路径 ## 例子 $ gcc -v foo.c ... ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu" ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../x86_64-linux-gnu/include" #include "..." search starts here: #include <...> search starts here: /usr/lib/gcc/x86_64-linux-gnu/4.6/include /usr/local/include /usr/lib/gcc/x86_64-linux-gnu/4.6/include-fixed /usr/include/x86_64-linux-gnu /usr/include End of search list. ... ## 技巧 如上所示,使用`-v`选项可以打印出gcc搜索头文件的路径和顺序。当然,也可以使用`-###`选项 ## 贡献者 xmj ================================================ FILE: src/print-level-options.md ================================================ # 打印优化级别的对应选项 ## 例子 $ gcc -Q --help=optimizers The following options control optimizations: -O -Ofast -Os -falign-functions [disabled] -falign-jumps [disabled] -falign-labels [disabled] -falign-loops [disabled] -fasynchronous-unwind-tables [enabled] -fbranch-count-reg [enabled] -fbranch-probabilities [disabled] -fbranch-target-load-optimize [disabled] -fbranch-target-load-optimize2 [disabled] -fbtr-bb-exclusive [disabled] -fcaller-saves [disabled] -fcombine-stack-adjustments [disabled] -fcommon [enabled] -fcompare-elim [disabled] -fconserve-stack [disabled] -fcprop-registers [disabled] -fcrossjumping [disabled] -fcse-follow-jumps [disabled] -fcx-fortran-rules [disabled] -fcx-limited-range [disabled] -fdata-sections [disabled] -fdce [enabled] -fdefer-pop [disabled] -fdelayed-branch [disabled] -fdelete-null-pointer-checks [enabled] -fdevirtualize [disabled] -fdse [enabled] -fearly-inlining [enabled] -fexceptions [disabled] -fexpensive-optimizations [disabled] -ffinite-math-only [disabled] -ffloat-store [disabled] -fforward-propagate [disabled] -fgcse [disabled] -fgcse-after-reload [disabled] -fgcse-las [disabled] -fgcse-lm [enabled] -fgcse-sm [disabled] -fgraphite-identity [disabled] -fguess-branch-probability [disabled] -fhandle-exceptions -fif-conversion [disabled] -fif-conversion2 [disabled] -finline-functions [disabled] -finline-functions-called-once [enabled] -finline-small-functions [disabled] -fipa-cp [disabled] -fipa-cp-clone [disabled] -fipa-matrix-reorg [disabled] -fipa-profile [disabled] -fipa-pta [disabled] -fipa-pure-const [disabled] -fipa-reference [disabled] -fipa-sra [disabled] -fivopts [enabled] -fjump-tables [enabled] -floop-block [disabled] -floop-flatten [disabled] -floop-interchange [disabled] -floop-parallelize-all [disabled] -floop-strip-mine [disabled] -flto-report [disabled] -fltrans [disabled] -fmath-errno [enabled] -fmerge-all-constants [disabled] -fmerge-constants [disabled] -fmodulo-sched [disabled] -fmove-loop-invariants [enabled] -fnon-call-exceptions [disabled] -fnothrow-opt [disabled] -fomit-frame-pointer [disabled] -foptimize-register-move [disabled] -foptimize-sibling-calls [disabled] -fpack-struct [disabled] -fpack-struct= -fpeel-loops [disabled] -fpeephole [enabled] -fpeephole2 [disabled] -fpredictive-commoning [disabled] -fprefetch-loop-arrays [enabled] -freg-struct-return [disabled] -fregmove [disabled] -frename-registers [enabled] -freorder-blocks [disabled] -freorder-blocks-and-partition [disabled] -freorder-functions [disabled] -frerun-cse-after-loop [disabled] -freschedule-modulo-scheduled-loops [disabled] -frounding-math [disabled] -frtti [enabled] -fsched-critical-path-heuristic [enabled] -fsched-dep-count-heuristic [enabled] -fsched-group-heuristic [enabled] -fsched-interblock [enabled] -fsched-last-insn-heuristic [enabled] -fsched-pressure [disabled] -fsched-rank-heuristic [enabled] -fsched-spec [enabled] -fsched-spec-insn-heuristic [enabled] -fsched-spec-load [disabled] -fsched-spec-load-dangerous [disabled] -fsched-stalled-insns [disabled] -fsched-stalled-insns-dep [enabled] -fsched2-use-superblocks [disabled] -fschedule-insns [disabled] -fschedule-insns2 [disabled] -fsection-anchors [disabled] -fsel-sched-pipelining [disabled] -fsel-sched-pipelining-outer-loops [disabled] -fsel-sched-reschedule-pipelined [disabled] -fselective-scheduling [disabled] -fselective-scheduling2 [disabled] -fshort-double [disabled] -fshort-enums [enabled] -fshort-wchar [disabled] -fsignaling-nans [disabled] -fsigned-zeros [enabled] -fsingle-precision-constant [disabled] -fsplit-ivs-in-unroller [enabled] -fsplit-wide-types [disabled] -fstrict-aliasing [disabled] -fstrict-enums [disabled] -fthread-jumps [disabled] -fno-threadsafe-statics [enabled] -ftoplevel-reorder [enabled] -ftrapping-math [enabled] -ftrapv [disabled] -ftree-bit-ccp [disabled] -ftree-builtin-call-dce [disabled] -ftree-ccp [disabled] -ftree-ch [disabled] -ftree-copy-prop [disabled] -ftree-copyrename [disabled] -ftree-cselim [enabled] -ftree-dce [disabled] -ftree-dominator-opts [disabled] -ftree-dse [disabled] -ftree-forwprop [enabled] -ftree-fre [disabled] -ftree-loop-distribute-patterns [disabled] -ftree-loop-distribution [disabled] -ftree-loop-if-convert [enabled] -ftree-loop-if-convert-stores [disabled] -ftree-loop-im [enabled] -ftree-loop-ivcanon [enabled] -ftree-loop-optimize [enabled] -ftree-lrs [disabled] -ftree-phiprop [enabled] -ftree-pre [disabled] -ftree-pta [enabled] -ftree-reassoc [enabled] -ftree-scev-cprop [enabled] -ftree-sink [disabled] -ftree-slp-vectorize [enabled] -ftree-sra [disabled] -ftree-switch-conversion [disabled] -ftree-ter [disabled] -ftree-vect-loop-version [enabled] -ftree-vectorize [disabled] -ftree-vrp [disabled] -funit-at-a-time [enabled] -funroll-all-loops [disabled] -funroll-loops [disabled] -funsafe-loop-optimizations [disabled] -funsafe-math-optimizations [disabled] -funswitch-loops [disabled] -funwind-tables [disabled] -fvar-tracking [enabled] -fvar-tracking-assignments [enabled] -fvar-tracking-assignments-toggle [disabled] -fvar-tracking-uninit [disabled] -fvariable-expansion-in-unroller [disabled] -fvect-cost-model [enabled] -fvpt [disabled] -fweb [enabled] -fwhole-program [disabled] -fwpa [disabled] -fwrapv [disabled] ## 技巧 如上所示,使用`-Q --help=optimizers`选项可以打印出gcc的所有优化(相关的)选项,以及缺省情况下它们是否打开。类似的,你也可以查看不同优化级别下,这些优化选项是否打开: $ gcc -Q --help=optimizers -O $ gcc -Q --help=optimizers -O1 $ gcc -Q --help=optimizers -O2 $ gcc -Q --help=optimizers -O3 $ gcc -Q --help=optimizers -Og $ gcc -Q --help=optimizers -Os $ gcc -Q --help=optimizers -Ofast 详情参见[gcc手册](https://gcc.gnu.org/onlinedocs/gcc/Overall-Options.html#Overall-Options) ## 贡献者 xmj ================================================ FILE: src/print-predefined-macros.md ================================================ # 打印gcc预定义的宏信息 ## 例子 [root@linux:~]$ gcc -dM -E - < /dev/null #define __DBL_MIN_EXP__ (-1021) #define __FLT_MIN__ 1.17549435e-38F #define __CHAR_BIT__ 8 #define __WCHAR_MAX__ 2147483647 #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1 #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1 #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1 #define __DBL_DENORM_MIN__ 4.9406564584124654e-324 #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1 #define __FLT_EVAL_METHOD__ 0 #define __unix__ 1 #define __x86_64 1 #define __DBL_MIN_10_EXP__ (-307) #define __FINITE_MATH_ONLY__ 0 #define __GNUC_PATCHLEVEL__ 7 ## 技巧 如上所示,使用“`gcc -dM -E - < /dev/null`”命令就可以显示出gcc预定义的宏信息。“`-dM`”生成预定义的宏信息,“`-E`”表示预处理操作完成后就停止,不再进行下面的操作。此外,也可以使用这个命令:“`echo | gcc -dM -E -`”。 详情参见[gcc手册](https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html#index-dM-908) ## 贡献者 nanxiao ================================================ FILE: src/save-temps.md ================================================ # 保存临时文件 ## 例子 $ gcc -save-temps a/foo.c $ ls foo.* foo.c foo.i foo.o foo.s $ gcc -save-temps=obj a/foo.c -o a/foo $ ls a foo foo.c foo.i foo.o foo.s ## 技巧 如上所示,使用选项`-save-temps`可以保存gcc运行过程中生成的临时文件。这些中间文件的名字是基于源文件而来,并且保存在当前目录下。 如果你在不同目录下有重名的源文件,那么中间文件就会有冲突了。此时,你可以使用`-save-temps=obj`来指定中间文件名基于目标文件而定,并保存在目标文件所在目录下。 详情参见[gcc手册](https://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html#Debugging-Options) ## 贡献者 xmj ================================================ FILE: src/set-dynamic-linker.md ================================================ # 设置动态连接器 ## 技巧 有人问我,如何通过选项来指定动态连接器,而不使用缺省系统自带的动态连接器。我后来查了下ld的手册,有这么一个选项: -Ifile --dynamic-linker=file Set the name of the dynamic linker. This is only meaningful when generating dynamically linked ELF executables. The default dynamic linker is normally correct; don't use this unless you know what you are doing. 看起来,可以通过如下方式来完成: $ gcc foo.c -Wl,-I/home/xmj/tmp/ld-2.15.so $ ldd a.out linux-vdso.so.1 => (0x00007fffce5fe000) /usr/local/lib/libtrash.so (0x00007f1980477000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f19800a3000) libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f197fe9e000) /home/xmj/tmp/ld-2.15.so => /lib64/ld-linux-x86-64.so.2 (0x00007f1980485000) 注意,tmp目录下的动态连接器因为也是动态连接的,所以它本身是依赖系统缺省的动态连接器。 详情参见[ld手册](https://sourceware.org/binutils/docs-2.24/ld/Options.html#Options) ## 贡献者 xmj ================================================ FILE: src/specify-language.md ================================================ # 指定语言类型 ## 技巧 gcc是通过文件名后缀来判断源代码语言类型的。 如果你从标准输入把源码传给gcc,那么就需要通过`-x`选项显式的指定语言类型: $ echo "int x;" | gcc -S -x c - $ cat ./-.s .file "" .comm x,4,4 .ident "GCC: (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3" .section .note.GNU-stack,"",@progbits 详情参见[gcc手册](https://gcc.gnu.org/onlinedocs/gcc/Overall-Options.html#Overall-Options) ## 贡献者 xmj ================================================ FILE: src/syntax-only.md ================================================ # 只做语法检查 ## 例子 $ cat foo.c union u { char c; int i; } $ gcc -fsyntax-only foo.c foo.c:4:1: error: expected identifier or ‘(’ at end of input ## 技巧 如上所示,使用`-fsyntax-only`选项可以只做语法检查,不进行实际的编译输出。 详情参见[gcc手册](https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-fsyntax-only-274) ## 贡献者 xmj ================================================ FILE: src/thread-sanitizer.md ================================================ # 利用Thread Sanitizer工具检查数据竞争的问题 ## 例子 #include int Global; void *Thread1(void *x) { Global = 42; return x; } int main(void) { pthread_t t; pthread_create(&t, NULL, Thread1, NULL); Global = 43; pthread_join(t, NULL); return Global; } ## 技巧 gcc从`4.8`版本起,集成了`Address Sanitizer`工具,可以用来检查数据竞争的问题(编译时指定“`-fsanitize=thread -fPIE -pie`”)。以上面程序为例: gcc -fsanitize=thread -fPIE -pie -g -o a a.c -lpthread 执行`a`程序: [root@localhost nan]# ./a ================== WARNING: ThreadSanitizer: data race (pid=14545) Write of size 4 at 0x7f055b4802b0 by thread T1: #0 Thread1 /home/nan/a.c:4 (a+0x000000000a87) Previous write of size 4 at 0x7f055b4802b0 by main thread: #0 main /home/nan/a.c:10 (a+0x000000000ae8) Location is global 'Global' of size 4 at 0x7f055b4802b0 (a+0x0000002012b0) Thread T1 (tid=14547, running) created by main thread at: #0 pthread_create /opt/gcc-4.9.2/src/gcc-4.9.2/libsanitizer/tsan/tsan_interceptors.cc:877 (libtsan.so.0+0x00000004aa83) #1 main /home/nan/a.c:9 (a+0x000000000ad9) SUMMARY: ThreadSanitizer: data race /home/nan/a.c:4 Thread1 ================== ThreadSanitizer: reported 1 warnings 可以看到,执行程序时检测出了对`Global`变量的竞争访问。 详情参见[gcc手册](https://gcc.gnu.org/onlinedocs/gcc-4.9.2/gcc/Debugging-Options.html#index-fsanitize_003dthread-595) ## 贡献者 nanxiao ================================================ FILE: src/turn-on-warnings.md ================================================ # 打开警告信息 ## 技巧 你的程序编译通过了,但并不意味着已经万事大吉,也许还存在一些不规范的地方,或者一些错误隐患。建议,使用`-Wall`选项打开所有的警告信息,把所有的警告都处理掉。 $ gcc -Wall ... 详情参见[gcc手册](https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html#Preprocessor-Options) ## 贡献者 xmj ================================================ FILE: src/undefine-macro.md ================================================ # 在命令行中取消宏定义 ## 技巧 类似于`-D`选项,你可以使用`-U`选项在命令行中取消一个宏的定义,比如: $ gcc -U DEBUG macro.c 中间可以没有空格: $ gcc -UDEBUG macro.c 详情参见[gcc手册](https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html#Preprocessor-Options) ## 贡献者 xmj ================================================ FILE: src/verbose-asm.md ================================================ # 生成有详细信息的汇编文件 ## 例子 #include int main(void) { int i; for (i = 0; i < 10; i++) printf("%d ", i); putchar ('\n'); return 0; } ## 技巧 使用`-fverbose-asm`选项就可以生成带有详细信息的汇编文件: $ gcc -S -fverbose-asm foo.c $ cat foo.s .file "foo.c" # GNU C (Ubuntu/Linaro 4.6.3-1ubuntu5) version 4.6.3 (x86_64-linux-gnu) # compiled by GNU C version 4.6.3, GMP version 5.0.2, MPFR version 3.1.0-p3, MPC version 0.9 # GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 # options passed: -imultilib . -imultiarch x86_64-linux-gnu foo.c # -mtune=generic -march=x86-64 -fverbose-asm -fstack-protector # options enabled: -fasynchronous-unwind-tables -fauto-inc-dec # -fbranch-count-reg -fcommon -fdelete-null-pointer-checks -fdwarf2-cfi-asm # -fearly-inlining -feliminate-unused-debug-types -ffunction-cse -fgcse-lm # -fident -finline-functions-called-once -fira-share-save-slots # -fira-share-spill-slots -fivopts -fkeep-static-consts # -fleading-underscore -fmath-errno -fmerge-debug-strings # -fmove-loop-invariants -fpeephole -fprefetch-loop-arrays # -freg-struct-return -fsched-critical-path-heuristic # -fsched-dep-count-heuristic -fsched-group-heuristic -fsched-interblock # -fsched-last-insn-heuristic -fsched-rank-heuristic -fsched-spec # -fsched-spec-insn-heuristic -fsched-stalled-insns-dep -fshow-column # -fsigned-zeros -fsplit-ivs-in-unroller -fstack-protector # -fstrict-volatile-bitfields -ftrapping-math -ftree-cselim -ftree-forwprop # -ftree-loop-if-convert -ftree-loop-im -ftree-loop-ivcanon # -ftree-loop-optimize -ftree-parallelize-loops= -ftree-phiprop -ftree-pta # -ftree-reassoc -ftree-scev-cprop -ftree-slp-vectorize # -ftree-vect-loop-version -funit-at-a-time -funwind-tables # -fvect-cost-model -fverbose-asm -fzero-initialized-in-bss # -m128bit-long-double -m64 -m80387 -maccumulate-outgoing-args # -malign-stringops -mfancy-math-387 -mfp-ret-in-387 -mglibc -mieee-fp # -mmmx -mno-sse4 -mpush-args -mred-zone -msse -msse2 -mtls-direct-seg-refs # Compiler executable checksum: 75e879ed14f91af504f4150eadeaa0e6 .section .rodata .LC0: .string "%d " .text .globl main .type main, @function main: .LFB0: .cfi_startproc pushq %rbp # .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp #, .cfi_def_cfa_register 6 subq $16, %rsp #, movl $0, -4(%rbp) #, i jmp .L2 # .L3: movl $.LC0, %eax #, D.2049 movl -4(%rbp), %edx # i, tmp62 movl %edx, %esi # tmp62, movq %rax, %rdi # D.2049, movl $0, %eax #, call printf # addl $1, -4(%rbp) #, i .L2: cmpl $9, -4(%rbp) #, i jle .L3 #, movl $10, %edi #, call putchar # movl $0, %eax #, D.2050 leave .cfi_def_cfa 7, 8 ret .cfi_endproc .LFE0: .size main, .-main .ident "GCC: (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3" .section .note.GNU-stack,"",@progbits 可以看到,在汇编文件中给出了gcc所使用的具体选项,以及汇编指令操作数所对应的源程序(或中间代码)中的变量。 详情参见[gcc手册](https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#index-fverbose-asm-2614) ## 贡献者 xmj ================================================ FILE: src/warnings-treated-as-errors.md ================================================ # all warnings being treated as errors ## 技巧 在ubuntu系统下编译一个程序包,有时会遇到这样的错误: $ make ... cc1: all warnings being treated as errors 这是因为缺省的CFLAGS里含有`-Werror`选项,将警告信息升级为错误。当然,一方面这可以让你重视这些可能会带来隐患的警告信息;但,如果你不想修改源码,也可以把这个选项关掉,通过修改Makefile或者使用命令行: $ make CFLAGS="... -Wno-error" 详情参见[gcc手册](https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html#Preprocessor-Options) ## 贡献者 xmj ================================================ FILE: utils/build.go ================================================ // 代码源自https://github.com/astaxie/build-web-application-with-golang.git package main import ( "fmt" "github.com/fairlyblank/md2min" "io/ioutil" "os" "path/filepath" "regexp" "strings" ) // 定义一个访问者结构体 type Visitor struct{} func (self *Visitor) md2html(arg map[string]string) error { from := arg["from"] to := arg["to"] err := filepath.Walk(from+"/", func(path string, f os.FileInfo, err error) error { if f == nil { return err } if f.IsDir() { return nil } if (f.Mode() & os.ModeSymlink) > 0 { return nil } if !strings.HasSuffix(f.Name(), ".md") { return nil } file, err := os.Open(path) if err != nil { return err } input_byte, _ := ioutil.ReadAll(file) input := string(input_byte) input = regexp.MustCompile(`\[(.*?)\]\(?\)`).ReplaceAllString(input, "[$1](<$2.html>)") if f.Name() == "README.md" { input = regexp.MustCompile(`https:\/\/github\.com\/astaxie\/build-web-application-with-golang\/blob\/master\/`).ReplaceAllString(input, "") } // 以#开头的行,在#后增加空格 // 以#开头的行, 删除多余的空格 input = FixHeader(input) // 删除页面链接 input = RemoveFooterLink(input) var out *os.File filename := strings.Replace(f.Name(), ".md", ".html", -1) fmt.Println(to + "/" + filename) if out, err = os.Create(to + "/" + filename); err != nil { fmt.Fprintf(os.Stderr, "Error creating %s: %v", f.Name(), err) os.Exit(-1) } defer out.Close() md := md2min.New("none") err = md.Parse([]byte(input), out) if err != nil { fmt.Fprintln(os.Stderr, "Parsing Error", err) os.Exit(-1) } return nil }) return err } func FixHeader(input string) string { re_header := regexp.MustCompile(`(?m)^#.+$`) re_sub := regexp.MustCompile(`^(#+)\s*(.+)$`) fixer := func(header string) string { s := re_sub.FindStringSubmatch(header) return s[1] + " " + s[2] } return re_header.ReplaceAllStringFunc(input, fixer) } func RemoveFooterLink(input string) string { re_footer := regexp.MustCompile(`(?m)^#{2,} links.*?\n(.+\n)*`) return re_footer.ReplaceAllString(input, "") } func main() { html := os.Getenv("HTML") if html == "" { html = "." } src := os.Getenv("WORKDIR") if src == "" { src = "." } arg := map[string]string{ "from": src, "to": html, } v := &Visitor{} err := v.md2html(arg) if err != nil { fmt.Printf("filepath.Walk() returned %v\n", err) } }