9 Eylül 2019 Pazartesi

gcc seçenekleri

gcc
gcc GNU ile kullanılan derleyici. Aslında gcc jenerik bir derleyici. Verilen dosya uzantısına göre gerekli olan derleyiciyi çağırıyor. Örneğin c++ dosyası verilirse g++ derleyicisini çağırıyor. Bu konu ile ilgili daha detaylı bilgiyi burada bulabilirsiniz.

gcc genelde şu dizine kurulur.
/usr/bin/gcc

g++
Bir c++ programını derlerken aslında g++ ile beraber bazen cc1 veya cc1plus isimli bir başka programın daha çalıştığını görüyoruz. cc1plus, g++ tarafından çağırılan gerçek derleyici oluyor.

Built-in Functions
gcc birçok metodu built-in sağladığı için bazı kütüphanaler ile (örneğin matematik kütphanesi libm.so) linklemek gerekmiyor. Açıklaması şöyle
6.59 Other Built-in Functions Provided by GCC
GCC provides a large number of built-in functions other than the ones mentioned above. Some of these are for internal use in the processing of exceptions or variable-length argument lists and are not documented here because they may change from time to time; we do not recommend general use of these functions.
The remaining functions are provided for optimization purposes.
...
The ISO C99 functions _Exit, acoshf, acoshl, acosh, asinhf, asinhl, asinh, atanhf, atanhl, atanh, cabsf, cabsl, cabs, cacosf, cacoshf, cacoshl, cacosh, cacosl, cacos, cargf, cargl, carg, casinf, casinhf, casinhl, casinh, casinl, casin, catanf, catanhf, catanhl, catanh, catanl, catan, cbrtf, cbrtl, cbrt, ccosf, ccoshf, ccoshl, ccosh, ccosl, ccos, cexpf, cexpl, cexp, cimagf, cimagl, cimag, clogf, clogl, clog, conjf, conjl, conj, copysignf, copysignl, copysign, cpowf, cpowl, cpow, cprojf, cprojl, cproj, crealf, creall, creal, csinf, csinhf, csinhl, csinh, csinl, csin, csqrtf, csqrtl, csqrt, ctanf, ctanhf, ctanhl, ctanh, ctanl, ctan, erfcf, erfcl, erfc, erff, erfl, erf, exp2f, exp2l, exp2, expm1f, expm1l, expm1, fdimf, fdiml, fdim, fmaf, fmal, fmaxf, fmaxl, fmax, fma, fminf, fminl, fmin, hypotf, hypotl, hypot, ilogbf, ilogbl, ilogb, imaxabs, isblank, iswblank, lgammaf, lgammal, lgamma, llabs, llrintf, llrintl, llrint, llroundf, llroundl, llround, log1pf, log1pl, log1p, log2f, log2l, log2, logbf, logbl, logb, lrintf, lrintl, lrint, lroundf, lroundl, lround, nearbyintf, nearbyintl, nearbyint, nextafterf, nextafterl, nextafter, nexttowardf, nexttowardl, nexttoward, remainderf, remainderl, remainder, remquof, remquol, remquo, rintf, rintl, rint, roundf, roundl, round, scalblnf, scalblnl, scalbln, scalbnf, scalbnl, scalbn, snprintf, tgammaf, tgammal, tgamma, truncf, truncl, trunc, vfscanf, vscanf, vsnprintf and vsscanf are handled as built-in functions except in strict ISO C90 mode (-ansi or -std=c90).
...

Bazı gcc/g++ seçenekleri
-ansi
Açıklaması şöyle
-ansi

In C mode, this is equivalent to -std=c90. In C++ mode, it is equivalent to -std=c++98. 
Ansi uyumluluğunu dikkate alarak  derler.
Örnek
Şöyle yaparız.
gcc -ansi -Wall -pedantic code.c -o code...
Örnek
Şöyle yaparız.
g++ -O2 -Wall -Werror -Wextra -ansi -flto
-c
Verilen kaynak dosyayı sadece derler ancak linklemez. İsmi belirtilen kaynak dosyaları şöyle derleriz.
gcc -c xyz.c abc.c
 -dM
Tüm gömülü (built-in) preprocessor macrolarını yazar.
Örnek
Windows'ta _WIN32 de gömülü bir macro'dur

Örnek
Şöyle yaparız.
$ g++ -dM -E -x c++ - < /dev/null
Sıralı görmek için şöyle yaparız.
g++ -x c++ -dM -E - | sort
 -dumpmachine
Açıklaması şöyle.
Take a look at lscpu and gcc -dumpmachine to find out what CPU type you have.
-e
Açıklaması şöyle. GNU Runtime - Main'den Önce Çağrılabilecek Metodlar yazısına bakabilirsiniz.
The -e command line flag redefines the actual entry point of your program, not the “user” entry point. By default, using GCC with the GNU C standard library (glibc) this entry point is called _start, and it performs further setup before invoking the user-provided main function.
-E
Preprocessing aşamasından sonra durur. Böylece preprocessing'den geçmiş kaynak kodu görebilmemizi sağlar.  Elimizde şöyle bir kod olsun.
#include <stdio.h>
#define decode(s,t,u,m,p,e,d) m##s##u##t
#define begin decode(a,n,i,m,a,t,e)

int begin()
{
    printf("Ha HA see how it is?? ");
}
Bu kodu şöyle derlersek
gcc -E source.c

Çıktı olarak macroların gittiğini görürürüz.
int main()
{
    printf("Ha HA see how it is?? ");
}
Eğer istersek çıktıyı dosyaya yönlendirebiliriz.
gcc -C -E foo.c > foo.i
-faggressive-loop-optimizations
Açıklaması şöyle. Döngü içinde signed integer overflow olmaması gerekir.
This option tells the loop optimizer to use language constraints to derive bounds for the number of iterations of a loop. This assumes that loop code does not invoke undefined behavior by for example causing signed integer overflows or out-of-bound array accesses. The bounds for the number of iterations of a loop are used to guide loop unrolling and peeling and loop exit test optimizations. This option is enabled by default.
Elimizde şöyle bir kod olsun.

#include <iostream>
int main()
{
    for (int i = 0; i < 300; i++)
        std::cout << i << " " << i * 12345678 << std::endl;
}
Undefined behavior yüzünden çıktı 299'da bitmeyebilir. Şu çıktıyı alırız.

0 0
1 12345678
2 24691356
...
4167 -95167326
4168 -82821648
4169 -7047597

-fdump-tree-optimized
Şöyle yaparız.

$ g++ -std=c++1y -c -O3 -fdump-tree-optimized ./round.cpp
Çıktı olarak round.cpp.165t.optimized dosyası oluşur. Elimizde şöyle metodlar olsun.

std::int64_t my_cast(double d)
{
  auto t = static_cast<std::int64_t>(d);
  return t;
}

std::int64_t my_round(double d)
{
  auto t = std::round(d);
  return t;
}
Bu metodların nasıl çalıştığı şöyle görülebilir
;; Function int64_t my_cast(double) (_Z7my_castd, funcdef_no=224, decl_uid=4743$

int64_t my_cast(double) (double d)
{
  long int t;

  <bb 2>:
  t_2 = (long int) d_1(D);
  return t_2;
}


;; Function int64_t my_round(double) (_Z8my_roundd, funcdef_no=225, decl_uid=47$

int64_t my_round(double) (double d)
{
  double t;
  int64_t _3;

  <bb 2>:
  t_2 = round (d_1(D));
  _3 = (int64_t) t_2;
  return _3;
}
-ffast-math
Açıklaması şöyle
Sets the options -fno-math-errno, -funsafe-math-optimizations, -ffinite-math-only, -fno-rounding-math, -fno-signaling-nans, -fcx-limited-range and -fexcess-precision=fast. ...
-finput-charset
Açıklaması şöyle.
By default gcc interprets the source code as encoded in UTF-8. Compile-time options exist to change that, but it is recommendedd to keep everything in UTF-8 on Linux. Sources that come from Windows are probably not encoded in UTF-8 and need to be recoded. Use the iconv utility for that;l. If the source is associated with a particular legacy code page, try that code page name as the source encoding.
Şöyle yaparız.
$ /usr/local/gcc-5.2/bin/gcc \
    -finput-charset=UTF-8 -fextended-identifiers \
    -o circle circle.c
Visual Studio UTF-8 without BOM olarak kaydettiği için gcc sorunsuz olarak kaynak kodu okuyabilir.

-fms-extensions
Açıklaması şöyle. Bu seçeneği başlangıçta etkin değildir. Kapatmak için -fno-ms-extensions kullanılır. gcc ile Microsoft dosyalarının birlikte kullanılabilmesini sağlar.
Accept some non-standard constructs used in Microsoft header files.
Disable Wpedantic warnings about constructs used in MFC.
-fno-builtin
İlk olarak burada gördüm.

-fno-elide-constructors
RVO optimizasyonunu devre dışı bırakır.
g++ -fno-elide-constructors

fno-math-errno
Açıklaması şöyle. errno değişkeni atanmaz.
-fno-math-errno
           Do not set "errno" after calling math functions that are executed
           with a single instruction, e.g., "sqrt".  A program that relies on
           IEEE exceptions for math error handling may want to use this flag
           for speed while maintaining IEEE arithmetic compatibility.

           This option is not turned on by any -O option since it can result
           in incorrect output for programs that depend on an exact
           implementation of IEEE or ISO rules/specifications for math
           functions. It may, however, yield faster code for programs that do
           not require the guarantees of these specifications.

           The default is -fmath-errno.

           On Darwin systems, the math library never sets "errno".  There is
           therefore no reason for the compiler to consider the possibility
           that it might, and -fno-math-errno is the default.
-fno-exceptions
Şöyle yaparız. Exception desteğinin kaldırılması tam olarak ne işe yarar bilmiyorum.
$ g++ -dM -E -x c++ -fno-exceptions
-fno-rtti
Açıklaması şöyle.
Disable generation of information about every class with virtual functions for use by the C++ run-time type identification features (dynamic_cast and typeid). If you don't use those parts of the language, you can save some space by using this flag. Note that exception handling uses the same information, but G++ generates it as needed. The dynamic_cast operator can still be used for casts that do not require run-time type information, i.e. casts to "void *" or to unambiguous base classes.
-fopenmp
openmp kullanarak derleriz.
g++ ptr_vector.cpp -fopenmp -DOPTION=1
Şöyle yaparız.
g++ -fopenmp myred.cc -o myred
-fPIC veya -fpic
PIC Position Independent Code anlamına gelir. .so derleken kullanırız. Açıklaması şöyle. Benzer bir açıklama burada.
Code that is built into shared libraries should normally be position-independent code, so that the shared library can readily be loaded at (more or less) any address in memory. The -fPIC option ensures that GCC produces such code.cpp_dec_float_100
Açıklaması şöyle.
If supported for the target machine, emit position-independent code, suitable for dynamic linking and avoiding any limit on the size of the global offset table. This option makes a difference on the m68k, PowerPC and SPARC. Position-independent code requires special support, and therefore works only on certain machines.
-FPIC kullanılmamışsa şöyle bir hata alırız.
`.bss' can not be used when making a shared object; recompile with -fPIC
Şöyle yaparız.
gcc -o liba.so -fPIC -shared liba.c
-fprofile-arcs
Şöyle yaparız.
g++ -O0 -ggdb3 -fprofile-arcs -ftest-coverage -std=c++11 -pthread test.cpp
-ftest-coverage
Şöyle yaparız.
g++ -O0 -ggdb3 -fprofile-arcs -ftest-coverage -std=c++11 -pthread test.cpp
-fsanitize=thread
Örnek
Çıktı şöyle olabilir.
WARNING: ThreadSanitizer: unlock of an unlocked mutex (or by a wrong thread)
Örnek
Şöyle yaparız.
g++ -std=c++11 -O0 -g -fsanitize=thread issue49.cpp -o issue49 -pthread
Çıktı olarak şuna benzer bir şey alırız.
==================
WARNING: ThreadSanitizer: data race (pid=17220)
  Read of size 4 at 0x0000006051c0 by thread T1:
    #0 FakeQueue::try_dequeue(int&) issue49.cpp:26 (issue49+0x000000402bcd)
    ...

  Previous write of size 4 at 0x0000006051c0 by main thread:
    #0 FakeQueue::enqueue(int) issue49.cpp:16 (issue49+0x000000402a90)
    ...

  Location is global 'q' of size 4008 at 0x0000006051c0 (issue49+0x0000006051c0)

  Thread T1 (tid=17222, running) created by main thread at:
    #0 pthread_create <null> (libtsan.so.0+0x000000027a67)
    ...

SUMMARY: ThreadSanitizer: data race issue49.cpp:26 FakeQueue::try_dequeue(int&)
==================
ThreadSanitizer: reported 1 warnings
-fsanitize=undefined
Açıklaması şöyle
In order to check your program with ubsan, compile and link the program with -fsanitize=undefined option. Such instrumented binaries have to be executed; if ubsan detects any problem, it outputs a “runtime error:” message, and in most cases continues executing the program. There is a possibility of making these diagnostic messages abort — just use the option -fno-sanitize-recover.
Elimizde şöyle bir kod olsun.
int main() {
    int i = 23;
    i <<= 32; 
}
Bu kodu çalıştırınca şu çıktıyı alırız.
runtime error: shift exponent 32 is too large for 32-bit type 'int'
Bir başka kullanım şekli ve açıklaması şöyle. Bu özellik GCC 6 optimizer ile geliyor.
Value range propagation now assumes that the this pointer of C++ member functions is non-null. This eliminates common null pointer checks but also breaks some non-conforming code-bases (such as Qt-5, Chromium, KDevelop). As a temporary work-around -fno-delete-null-pointer-checks can be used. Wrong code can be identified by using -fsanitize=undefined.
Tüm problem C tarzı kodlamanın C++ diline uygulanmasından kaynaklanıyor.

-fstrict-aliasing
Açıklaması şöyle
Pay special attention to code like this:
      union a_union {
        int i;
        double d;
      };

      int f() {
        union a_union t;
        t.d = 3.0;
        return t.i;
      }
The practice of reading from a different union member than the one most recently written to (called “type-punning”) is common. Even with -fstrict-aliasing, type-punning is allowed,provided the memory is accessed through the union type. So, the code above works as expected. See Structures unions enumerations and bit-fields implementationHowever, this code might not:
      int f() {
        union a_union t;
        int* ip;
        t.d = 3.0;
        ip = &t.i;
        return *ip;
      }
-funsigned-char
İki seçenek var. char tipinin signed veya unsigned olmasın belirleyebiliriz. Varsayılan değer signed olmasıdır.
-funsigned-char
-fsigned-char
gcc seçeneklerini görmek için şöyle yaparız.
$ gcc -dM -E -x c /dev/null | grep -i CHAR
#define __UINT_LEAST8_TYPE__ unsigned char
#define __CHAR_BIT__ 8
#define __WCHAR_MAX__ 0x7fffffff
#define __GCC_ATOMIC_CHAR_LOCK_FREE 2
#define __GCC_ATOMIC_CHAR32_T_LOCK_FREE 2
#define __SCHAR_MAX__ 0x7f
#define __WCHAR_MIN__ (-__WCHAR_MAX__ - 1)
#define __UINT8_TYPE__ unsigned char
#define __INT8_TYPE__ signed char
#define __GCC_ATOMIC_WCHAR_T_LOCK_FREE 2
#define __CHAR16_TYPE__ short unsigned int
#define __INT_LEAST8_TYPE__ signed char
#define __WCHAR_TYPE__ int
#define __GCC_ATOMIC_CHAR16_T_LOCK_FREE 2
#define __SIZEOF_WCHAR_T__ 4
#define __INT_FAST8_TYPE__ signed char
#define __CHAR32_TYPE__ unsigned int
#define __UINT_FAST8_TYPE__ unsigned char
-fverbose-asm
-S seçeneği ile birlikte kullanılır. Daha okunaklı assembly kodu üretir.

-g
Debug derler. 
Örnek
Şöyle yaparız.
cc -c source1/abc.c -DLINUX -D_LARGE_THREADS -D_THREAD_SAFE -D_REENTRANT -pthread
  -D_GNU_SOURCE -g -fPIC -O3  -lpthread  -lm  -lrt  -o object1/abc.o
Örnek
Şöyle yaparız
g++ -g main.cpp -o myprogram
-ggdb3
Şöyle yaparız.
g++ -O0 -ggdb3 -fprofile-arcs -ftest-coverage -std=c++11 -pthread test.cpp
--help
Şöyle yaparız.
gcc --help=optimizers
-I seçeneği
Açıklaması şöyle
"You can use -I to override a system header file, substituting your own version, since these directories are searched before the standard system header file directories."
-l 
verilen .so kütüphane ile linkler
Not 1: gcc ile libc.so (yani c runtime) otomatik olarak linklenir.
Not 2: g++ ile libstd++.so (yani c++ runtime) otomatik olarak linklenir.

Örnek
Şöyle yaparız. C projesini C++ run-time kütüphanesi ile linkleriz.
gcc main.c -lstdc++
Örnek
Şöyle yaparız.
gcc -static -Wall main.c -L. -ldmx -lusb -lrt -lasound -ljack -lfftw3 -g -o main
Dosya sisteminde libasound.so olması gerekir.
Örnek
Linkleme esnasında önce .o dosyalarını yazmak gerekir. Eğer şöyle kullanırsak
gcc foo.o -lz bar.o
gcc z kütüphanesini okuduktan sonra unutur. bar.o z kütüphanesini kullanıyorsa hata alırız.

-L
Linklenecek kütüphanelerin bulunduğu dizini belirtir.
gcc -static -Wall main.c -L. -ldmx -lusb
Eğer -L ile bir sürü dizin belirtmek zorunda kalıyorsak şu ortam değişkenini de kullanabiliriz.
export LIBRARY_PATH=$LIBRARY_PATH:/usr/local/lib/customlib
Şu kullanım yanlış. *.so şeklinde kullanamayız
-L /home/my_lib/boost_1_64_0/stage/lib/*.so
-m32
32 bit derleme yapar.
$> CXX='g++ -m32' make
-march
Açıklaması şöyle. Sayısal hesaplamaları hızlandırır.
which tells the compiler to tune generated code for the micro-architecture and ISA extensions of the host CPU.
Şöyle yapraız
-march=native
Şöyle yaparız.
-march=i586
Daha da eski işlemciler için şöyle yaparız.
-march=i486
veya
-march=i386
-msse2
32 bit ve SSE2 komutları ile derlemek için şöyle yaparız.
-m32 -msse2

-nostartfiles
main metodu kullanmak istemezsek şöyle yaparız.
gcc -nostartfiles nomain.c
Dosyamız şöyledir.
#include <stdio.h>
#include <stdlib.h>

_Noreturn void nomain(void)
{
  printf("Hello World...\n");
  printf("Successfully run without main...\n");
  exit(0);
}
-pg
Örnekte gprof için kodun instrument edilmesi gösterilmiş.

-o - object dosya
Belirtilen derleme işlemi sonunda oluşturulacak object dosyasının ismini belirtir.
gcc wrap_printf.c -c -o wrap_printf.o
Derleme işleminde assembly kodu da verilebilir.
gcc -c example.s -o example.o
-o - binary dosya
binary dosyanın ismini belirtir. main çalıştırılabilir bir dosyadır.
g++ -o main main.cpp Sum2.cpp
Binary dosya oluşturmak için gereken crt0, libc.so, ld komutu gibi şeyler -o seçeneği tarafından bizim için çağrılır. Yani şunu yapar.

g++ -c -o main.o main.cppld -o main main.o
cpp dosyalarının ve binary dosya ismi sırasının bir önemi yoktur. Şöyle de olabilirdi.
$ g++ main.cpp -o main
Binary dosya için object dosyaları da belirtebiliriz.
gcc -o xyz xyz.o abc.o
-O
Optimizasyon seviyesini belirtir. Bu seçenek veirlmezse optimizasyon yapılmaz. Açıklaması şöyle
gcc with no options is the same as gcc -O0.
03 sıkça kullanılır.
c++ -std=c++11 -O3 -o stoi_perf stoi_perf.cc
Anladığım kadarıyla -0'dan sonra 99'a kadar sayı verilebiliyor. Ancak benim gördüğüm en yüksek sayı -O3. -O4 verilse bile gcc itiraz etmeyip kendi içinde bir seviyeye ayarlıyor.  optimizasyon seviyeleri arasındaki fark şöyle görülebilir.
diff <(gcc -Q --help=optimizers -O4) <(gcc -Q --help=optimizers -O3)
-Ofast 
 Açıklaması şöyle
Disregard strict standards compliance. -Ofast enables all -O3 optimizations. It also enables optimizations that are not valid for all standard-compliant programs. It turns on -ffast-math
-fast-math seçeneğini etkinleştirir. Matematiksel işlemlerin çok daha hızlı olacak şekilde optimize edilmesini sağlar. İşlem sonuçları farklı çıkabilir. 
Örnek
-fast-math bir sayının Nan olduğunu tespit edemez. Açıklaması şöyle
-Ofast, among other things, activates GCC's -ffast-math mode, and -ffast-math, among other things, causes the compiler to generate code that assumes that NaN (and Inf) never occur.
Elimizde şu kod olsun
double pearson_corr = ...; //nan
cout << "pearson_corr = " << pearson_corr << endl;
if (isnan(pearson_corr))
  cout << "It is nan" << endl;
else
  cout << "Not nan" << endl;
}
Kodu şöyle derleyelim
c++ -Ofast test-r2.cc -lgsl -lgslcblas
Çıktı olarak "Not nan" yani yanlış cevabı alırız.

-pedantic
Extensionları devre dışı yaparak bazı hataları yakalamamızı sağlar.
$ gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
     -Wold-style-definition -Werror -pedantic -c foo.c
Örnekte sizeof(void) kullanılıyor anca void'in büyüklüğü yoktur . -pendatic bu hatayı yakalıyor.
void* p_ret = NULL;
malloc(sizeof(*p));
-pedantic-errors
Pendantic uyarıların hata olarak algılanmasını sağlar. Şöyle yaparız.
gcc -std=c11 -pedantic-errors x.c
Aşağıdaki kod parçasında birbiri ile uyumsuz iki pointer ataması yapılıyor.
int a;
double* p = a;
Şu hatayı alırız.
error: initialization from incompatible pointer type ...
  double* p = &a;
-Q
Optimizasyonla ilgili yardım şöyle alınabilir.
gcc -Q --help=optimizers -O3
-rpath
Uygulamanın .so dosyalarına bakacağı yolu atamak için şöyle yaparız.
gcc main.c -Wl,-rpath='$ORIGIN' -lfoo -lbar
Şöyle yaparız.
-L/home/user/boost/stage/lib -Wl,-rpath=/home/user/boost/stage/lib
-s
strip debug info demek. -g seçeneğinin tam tersini yapar. Eğer bu seçenek ile derlenmiş ise gdb ile açınca "(no debugging symbols found)...done" mesajı alırız.

-S
Assembly kodu üretir. Aşağıdaki komut example.S dosyası üretir.
gcc -Wall -O -fverbose-asm -S example.c
Üretilen kodun AT&T veya intel assembly'si şeklinde olacağı seçilebilir.
gcc -S -masm=att code.c
veya
gcc -S -masm=intel code.c
-shared
Shared kütüphane (.so dosyası ) oluşturmayı sağlar. Şöyle yaparız.
gcc -shared -o xyz.so xyz.o abc.o
Şöyle yaparız.
g++ a.cpp -o a.so -shared -fPIC
-stack
Şöyle yaparız.
gcc --stack,4194304 ...

-static
Harici kütüphaneler ile static linklememizi sağlar. Eğer harici kütüphane hem .so hem de .a sağlıyorsa -lkütüphane_ismi şeklinde kullanırsak sadece -static kelimesini eklemek yeterli.
g++ -static -o /tmp/bft_stc boost_formatted_time.cpp -lboost_date_time
glibc ile static linkle tavsiye edilmiyor. Açıklaması şöyle
The glibc-static package contains the C library static libraries
for -static linking.  You don't need these, unless you link statically,
which is highly discouraged.
-std - C++ için
Bir sürü geçenek ve bunların gcc uzantıları mevcut.
C++98[-std=c++98] through C++14[-std=c++14]
GNU++98[-std=gnu++98] through GNU++14[-std=gnu++14]
g++ 4.8 ile -std=c++0x vermek gerekiyor.

C++11 için  -std=c++11 verilebilir.

C++14 için şöyle yaparız.
g++ main.cpp -std=c++14 && ./a.out

C++17 için kısmi destek c++1z ile veriliyor.
g++ -Wshadow --std=c++1z -o main main.cpp 
istersek -std yerine uzun hali olan --std'yi kullanabiliriz. Şöyle yaparız.
$ g++ -std=c++1z -g -c -o t.o t.C
-std - C için
Bu seçeneğini tanımlamamak tehlikeli. Açıklaması şöyle
Note that gcc with no compiler options passed defaults to -std=gnu90 (gcc < 5.0) or -std=gnu11(gcc > 5.0). This gives you all the non-standard extensions enabled,
Yani şöyle yaparsak eski gcc için gnu90 seçeneği ile derlemeye çalışır. Bu ise oldukça eski bir standart
$ gcc main.c f1.c -o test
C99 için şöyle yapabiliriz.
-std=c99
C11 için şöyle yapabiliriz.
gcc -std=c11 -pedantic-errors -Wall -Wextra
C11 için şöyle yaparız
gcc -std=c11 -pedantic-errors
-v 
Şöyle yaparız.
gcc -v main.c
-S 
Assembly çıktı verir. İki dosyanın assembly farkını görmek için şöyle yaparız.
% gcc -S ex1.c; gcc -S ex2.c; diff -u ex1.s ex2.s
--- ex1.s       2018-07-17 08:19:25.425826813 +0300
+++ ex2.s       2018-07-17 08:19:25.441826756 +0300
@@ -1,4 +1,4 @@
-       .file   "ex1.c"
+       .file   "ex2.c"
        .text
        .section        .rodata
 .LC0:
-version
Örnek
Şöyle yaparız.
$ g++ --version
g++ (Ubuntu 4.8.4-2ubuntu1~14.04.1) 4.8.4
Copyright (C) 2013 Free Software Foundation, Inc.
Örnek
Şöyle yaparız.
$ g++ --version
g++ (GCC) 6.1.1 20160510 (Red Hat 6.1.1-2)
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Örnek
Şöyle yaparız.
$ g++ --version
g++ (GCC) 7.3.1 20180130 (Red Hat 7.3.1-2)
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Örnek
Şöyle yaparız.
$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/5/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v ...
Thread model: posix
gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.5) 
-Wall
gcc Warning Seçenekleri yazısına taşıdım.

-Warray-bounds
gcc Warning Seçenekleri yazısına taşıdım.

-Wextra
gcc Warning Seçenekleri yazısına taşıdım.

-Werror
gcc Warning Seçenekleri yazısına taşıdım.

-Weffc++
gcc Warning Seçenekleri yazısına taşıdım.

-Wpadded
gcc Warning Seçenekleri yazısına taşıdım.

-Wl,--as-needed
Kullanılmayan kütüphaneler ile linklemez. Açıklaması şöyle.
This will instruct the linker to not link against unused libraries.
Örnek
Şöyle yaparız
g++ -Wl,--as-needed main.cpp
-Wl,--gc-sections
Kullanılmayan section'ları dahil etmez. Şöyle yaparız.
-Wl,--gc-sections
Tam komut için şöyle yaparız.
gcc -Os -fdata-sections -ffunction-sections test.cpp -o test -Wl,--gc-sections
-Wl,--verbose
Linker için kullanılan script'i gösterir.

-Wshadow
Açıklaması şöyle.
In computer programming, variable shadowing occurs when a variable declared within a certain scope (decision block, method, or inner class) has the same name as a variable declared in an outer scope. At the level of identifiers (names, rather than variables), this is known as name masking. This outer variable is said to be shadowed by the inner variable, while the inner identifier is said to mask the outer identifier.
Şöyle kullanılır.
g++ -Wshadow --std=c++1z -o main main.cpp 
Örnek
Elimizde şöyle bir kod olsun. character değişkeni global değişkeni gölgeler.
#include <stdio.h>
char character = 'c';
int main (void)
{
    char character = 'b';
    printf("The current value of head is %c", character);
}
Örnek
Sınıf içindeki bir alan (member variable) ile sınıfın metoduna girilen parametre aynı isme sahipse yani birbirlerini gölgeliyorlarsa uyarı verir.

Elimizde şöyle bir kod olsun. a alanı ve a parametresi birbirlerini gölgeler.
struct A{
  A(int a, int b);
  int a, b;
};

A::A(int a, int b)
: a(a)
, b(b)
{}
-Wuninitialized
Bir değişken ilklendirilmeden kullanılırsa verilebilir. Uyarı verilmesi garanti değildir. Optimizasyon seviyesine göre uyarı es geçilebilir. Açıklaması şöyle
Warn if an automatic variable is used without first being initialized or if a variable may be clobbered by a setjmp call. [...]
Because these warnings depend on optimization, the exact variables or elements for which there are warnings depends on the precise optimization options and version of GCC used.
Örnek
Elimizde şöyle bir kod olsun.
#include <stdio.h>

int main()
{

  int i,len=12;

  /* printf("%d\n",i); */

  while(i!=len-1)
  {

    i++;
    len--;
  }

  return 0;
}
Şöyle yapalım. -Wall ile -Wuninitialized seçeneği de etkinleşir.
gcc -Wall -Wextra -pedantic
Çıktı olarak şunu alabiliriz.
warning: 'i' is used uninitialized in this function [-Wuninitialized]
Wunused-variable
Açıklaması şöyle
Warn whenever a local or static variable is unused aside from its declaration.
Elimizde şöyle bir kod olsun.
int check(){
  int x = 5;

  ++x; /* line 1.*/

  return 0;
}
Çıktı olarak şunu alırız.
warning: unused variable ‘x’ [-Wunused-variable]
-Wwrite-strings
Açıklaması şöyle.
When compiling C, give string constants the type const char[length] so that copying the address of one into a non-const char * pointer produces a warning. These warnings help you find at compile time code that can try to write into a string constant, but only if you have been very careful about using const in declarations and prototypes. Otherwise, it is just a nuisance. This is why we did not make -Wall request these warnings.
Şu tarz hataların yakalanmasını sağlar.
void f(char *s) {
  s[0] = '0';
}

int main() {
  char *s = "immutable";
  f("literal"); // oops
  f(s); // oops
  return 0;
}
-x seçeneği
Örnek
Pipe ile gelen veriyi derlemek için şöyle yaparız.
generate_source | g++ -o- -xc++ - | do_something_with_the_binary


Hiç yorum yok:

Yorum Gönder