1. 程式人生 > 其它 >C語言-Werror=sign-compare編譯錯誤解決方案

C語言-Werror=sign-compare編譯錯誤解決方案

在做C語言的一個小測試時,寫了下面的一段程式碼,涉及到有符號數和無符號數的大小比較。

// automatic type conversion
if (-1L < 1U)
{
        printf("sizeof(unsigned int)=%lu\nsizeof(signed long int)=%lu\n",
               sizeof(unsigned int), sizeof(signed long int));
        printf("\'-1L<1U\' since unsigned int is promoted to signed long type!\n");
}
if (-1L > 1UL)
{
        printf("sizeof(signed long int)=%lu\nsizeof(unsigned long int)=%l
               sizeof(signed long int), sizeof(unsigned long int));
        printf("\'-1L>1UL\' since signed long int is promoted to unsigned type!\n");
}

然後使用CMake編譯時顯示錯誤

/home/cv/playground_test/src/playground.cc:185:10: In function‘int main(int, const char**)’:
error: comparison between signed and unsigned integer expressions [-Werror=sign-compare]
  if (-1L > 1UL)
      ~~~~^~~~~
cc1plus: all warnings being treated as errors
CMakeFiles/playground.dir/build.make:62: recipe for target 'CMakeFile
s/playground.dir/src/playground.c.o' failed

有符號數與無符號數的比較,雖然有時確實需要特別注意,但也不至於上來就Fatal Error,尤其當我們明確需要這樣操作時。

-Werror是gcc/g++的配置引數,執行嚴格的錯誤檢查,這裡顯然是把一般的警告也作為錯誤對待了,在CMakeLists中將其去掉即可。
把如下展示的第11行

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror")

替換成

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")

然後重新編譯就不會報錯了。

修改後的CMakeLists.txt檔案內容如下

01 cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
02 project(playground)
03
04 #====================================================
05 ## C++ compiler options
06 #====================================================
07 set(CMAKE_CXX_STANDARD 11)
08 set(CMAKE_CXX_EXTENSIONS OFF)
09 set(CMAKE_CXX_STANDARD_REQUIRED ON)
10 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -Wall")
11 #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror")
12 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
13
14 set(CMAKE_BUILD_TYPE RELEASE)
15 # Set output directory to store executables, create if not exist
16 set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin)
17
18 ## Search for source files
19 set(SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src)
20 file(GLOB_RECURSE SRC_LIST "${SRC_DIR}/[^.]*.c*")
21
22 #====================================================
23 ## Compile target executables
24 #====================================================
25 foreach(src ${SRC_LIST})
26         string(REGEX REPLACE ".+/(.+)\\..*" "\\1" SRC_FILE_NAME ${src})
27         add_executable(${SRC_FILE_NAME} ${src})
28         set_target_properties(${SRC_FILE_NAME} PROPERTIES LINKER_LANGUAGE CXX)
29         target_link_libraries(${SRC_FILE_NAME} pthread)
30 endforeach(src ${SRC_LIST})

工程目錄結構和執行主機配置如下。

# Project tree structure
.
├── CMakeLists.txt
├── bin
│   └── playground
├── build
└── src
    └── playground.c

# Linux Ubuntu system information
cv@cv:~$ uname -a
Linux cv 4.18.0-25-generic #26~18.04.1-Ubuntu SMP Thu Jun 27 07:28:31 UTC 2019
x86_64 x86_64 x86_64 GNU/Linux

cv@cv:~$ g++ --version
g++ (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
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.

cv@cv:~$ cmake --version
cmake version 3.10.2
CMake suite maintained and supported by Kitware (kitware.com/cmake)

cv@cv:~$ make --version
GNU Make 4.1
Built for x86_64-pc-linux-gnu
Copyright (C) 1988-2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

這裡只是摘出相關的部分進行記錄和說明,完整測試程式碼及環境要求詳見 https://github.com/philleer/leetcode_test/tree/dev

(全文完)


本文作者 :phillee
發表日期 :2022年01月16日
本文連結https://www.cnblogs.com/phillee/p/15810793.html
版權宣告 :自由轉載-非商用-非衍生-保持署名(創意共享3.0許可協議/CC BY-NC-SA 3.0)。轉載請註明出處!
限於本人水平,如果文章和程式碼有表述不當之處,還請不吝賜教。