tech. tt

Teens Town 技術ブログ

gccとclangでのwarning messageの差

動作環境

OS

macOS Catalina 10.15.4
( MacBook Pro 16-inch )

Compiler

clangは、今日(2020年5月2日)時点でXcode由来のclangが最新だったのでそのまま

ちなみに血迷って brew install llvm して

export PATH="/usr/local/opt/llvm/bin:$PATH"
export LDFLAGS="-L/usr/local/opt/llvm/lib"
export CPPFLAGS="-I/usr/local/opt/llvm/include"

とすると、無事にclang v10.xに落ちます。やったね(滝汗)

homebrew由来のclangはXcodeのものとは別の部分にインストールされるので、上記の設定を外してコンソール再起動すれば大丈夫です。
brew install --with-toolchain llvmとフラグつけると違うインスコできるらしいですが、こっちは帰ってこれなくなりそう。

↑で焦ってbrew upgradeしたら鬼のように時間がかかった、っていう余談。 f:id:up-tri:20200502151544p:plain

一方、gccはhomebrew経由で導入後、コマンドが冗長 ( g++-9 とか gcc-9 とか ) だったのでエイリアス張っています。

alias g++="g++-9"
alias gcc="gcc-9"

どちらもC++14でコンパイル。

実行結果

実験したコードはこちら

LL.hpp

/**
 * alias of `long long int`
 */
#ifndef LLI
#define LLI signed long long int
#endif

/**
 * alias of `unsigned long long int`
 */
#ifndef ULLI
#define ULLI unsigned long long int
#endif

main.cpp

#include "./../libs/LL.hpp"
#include <iostream>

int main(int argc, char const *argv[])
{
  int ia = 18446744073709551615;
  long la = 18446744073709551615;
  LLI lla = 18446744073709551615;
  ULLI ulla = 18446744073709551615;

  std::cout << "ia = " << ia << std::endl;
  std::cout << "la = " << la << std::endl;
  std::cout << "lla = " << lla << std::endl;
  std::cout << "ulla = " << ulla << std::endl;
  return 0;
}

❯ c++ --version
Apple clang version 11.0.3 (clang-1103.0.32.29)
Target: x86_64-apple-darwin19.4.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

❯ c++ -std=c++14 ./main.cpp 
./main.cpp:7:12: warning: integer literal is too large to be represented in a signed integer type, interpreting
      as unsigned [-Wimplicitly-unsigned-literal]
  int ia = 18446744073709551615;
           ^
./main.cpp:8:13: warning: integer literal is too large to be represented in a signed integer type, interpreting
      as unsigned [-Wimplicitly-unsigned-literal]
  long la = 18446744073709551615;
            ^
./main.cpp:9:13: warning: integer literal is too large to be represented in a signed integer type, interpreting
      as unsigned [-Wimplicitly-unsigned-literal]
  LLI lla = 18446744073709551615;
            ^
./main.cpp:10:15: warning: integer literal is too large to be represented in a signed integer type,
      interpreting as unsigned [-Wimplicitly-unsigned-literal]
  ULLI ulla = 18446744073709551615;
              ^
./main.cpp:7:12: warning: implicit conversion from 'unsigned long long' to 'int' changes value from
      18446744073709551615 to -1 [-Wconstant-conversion]
  int ia = 18446744073709551615;
      ~~   ^~~~~~~~~~~~~~~~~~~~
5 warnings generated.
❯ g++ --version            
g++-9 (Homebrew GCC 9.3.0_1) 9.3.0
Copyright (C) 2019 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.

❯ g++ -std=c++14 ./main.cpp 
./main.cpp:7:12: warning: integer constant is so large that it is unsigned
    7 |   int ia = 18446744073709551615;
      |            ^~~~~~~~~~~~~~~~~~~~
./main.cpp:8:13: warning: integer constant is so large that it is unsigned
    8 |   long la = 18446744073709551615;
      |             ^~~~~~~~~~~~~~~~~~~~
./main.cpp:9:13: warning: integer constant is so large that it is unsigned
    9 |   LLI lla = 18446744073709551615;
      |             ^~~~~~~~~~~~~~~~~~~~
./main.cpp:10:15: warning: integer constant is so large that it is unsigned
   10 |   ULLI ulla = 18446744073709551615;
      |               ^~~~~~~~~~~~~~~~~~~~
./main.cpp: In function 'int main(int, const char**)':
./main.cpp:7:12: warning: overflow in conversion from '__int128' to 'int' changes value from '18446744073709551615' to '-1' [-Woverflow]
    7 |   int ia = 18446744073709551615;
      |            ^~~~~~~~~~~~~~~~~~~~

所感

  • clangの方がメッセージが親切
  • とは言えどそんなに大差無いので、競プロ等.cppファイルを直にコンパイルするときは、Homebrewで触りやすいgccでも良いのかなぁ(macの場合は特に)