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