C++常见编译WARNING小结

首先要说的是大家不要对Warning视而不见,有时候通过Warning确实可以找到一些隐患。其次,未来新增代码应不允许Warning出现,有Warning需要修改掉。以下是常见的Warning小结。

常见十大Warning

1.warning: comparison between signed and unsigned integer expressions [-Wsign-compare]

常见错误写法:

std::vector<int> photo_id;
for (int i = 0; i < photo_id.size(); i++)
{
}
std::string str_cookie(cookie);
int end = str_cookie.find(";");
if (end == std::string::npos)
{token = str_cookie.substr(begin + 6);
}
sprintf(buf, "%d\n", getpid());
if (write(fd, buf, strlen(buf)) != strlen(buf))
{return false;
}

总结起来就是int使用起来有点随意,没有注意当前的context。

正确写法为:

std::vector<int> photo_id;
for (std::size_t i = 0; i < photo_id.size(); i++)
{
}
std::string str_cookie(cookie);
std::size_t end = str_cookie.find(";");
if (end == std::string::npos)
{token = str_cookie.substr(begin + 6);
}
sprintf(buf, "%d\n", getpid());
if ((std::size_t)write(fd, buf, strlen(buf)) != strlen(buf))
{return false;
}

2.warning: unused parameter ‘XXX’ [-Wunused-parameter]

未使用的变量的Warning,比如以下代码,salen变量在函数里面都没有用上。

char* sock_ntop_ip(const struct sockaddr* sa, socklen_t salen)
{static char str[128];       /* Unix domain is largest */switch (sa->sa_family){case AF_INET:{struct sockaddr_in*  sin = (struct sockaddr_in*) sa;if (inet_ntop(AF_INET, &sin->sin_addr, str, sizeof(str)) == NULL){return (NULL);}return (str);}case AF_INET6:{struct sockaddr_in6* sin6 = (struct sockaddr_in6*) sa;str[0] = '[';if (inet_ntop(AF_INET6, &sin6->sin6_addr, str + 1, sizeof(str) - 1) == NULL) //??ֵ{return (NULL);}strcat(str, "]");return (str);}default:return (NULL);}
}

一般两种解决方法,一种是去掉该变量,一种是使用(void)方法。

char* sock_ntop_ip(const struct sockaddr* sa, socklen_t salen)
{(void)salen; //warning: unused parameter。。。。。。
}

3.warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]

比如代码:

int bs_reserve(int fd, BSJ **result) {return bs_reserve_job(fd, "reserve\r\n", result);
}
int bs_reserve_job(int fd, char *command, BSJ **result);

修正方法:

int bs_reserve(int fd, BSJ **result) {char command[] = "reserve\r\n";return bs_reserve_job(fd, command, result);
}

4.warning: “XXXX” redefined

比如以下代码:

PersonnalDeviceSetting.cpp定义了宏
#define PER_DEV_SQL_SECTION "ID,Type,Node,MAC,IPAddress,\
PrivatekeyMD5,RfidMD5,ConfigMD5,ContactMD5,SipAccount,SipPwd,ExpireTime<now() as  ExpireTime,NetGroupNumber,\
Location, RtspPwd, Flag,StairShow,Relay,Config,Community,DclientVer,SipType,FaceMD5"然而PersonnalDeviceSetting.h也定义了宏,造成了重复定义
#define PER_DEV_SQL_SECTION "ID,Type,Node,MAC,IPAddress,\
PrivatekeyMD5,RfidMD5,ConfigMD5,ContactMD5,SipAccount,SipPwd,ExpireTime<now() as  ExpireTime,NetGroupNumber,\
Location, RtspPwd, Flag,StairShow"

解决方法:去掉PersonnalDeviceSetting.h的宏定义

这种问题隐患较大,容易给开发人员带来困扰。

5.warning: no return statement in function returning non-void [-Wreturn-type]

这个Warning也比较常见,函数定义了返回值,但是实际没有返回值,隐患也比较大。

比如代码:

int CKafakProducer::ProduceMsg(KafkaProduceMsgPtr msg)
{std::unique_lock<std::mutex> lock(msg_mutex_);msg_list_.push_back(msg);condition_var_.notify_all();
}

如果外面有判断ProduceMsg的返回值,那么可能会带来不可预料的错误。修改方法,增返回值:

int CKafakProducer::ProduceMsg(KafkaProduceMsgPtr msg)
{std::unique_lock<std::mutex> lock(msg_mutex_);msg_list_.push_back(msg);condition_var_.notify_all();return 0;
}

6.warning: missing initializer for member

常见错误写法如下:

CacheConnectInfo info = {0};

有什么问题呢,比如代码

#include <iostream>struct S {int a;int b;
};int main() {S s { 1 }; // b will be automatically set to 0// and that's probably(?) not what you wantstd::cout<<"s.a = "<<s.a<<", s.b = "<<s.b<<std::endl;
}

结果输出是a=1,b=0,不是你预想的a=1,b=1。

所以避免这样的初始化,修正为:

CacheConnectInfo info;
memset(&info, 0, sizeof(info));

7.warning: format ‘%d’ expects argument of type ‘int’, but argument 4 has type ‘uint64_t {aka long unsigned int}’ [-Wformat=]

代码如下:

int CDeviceControl::SendRequestReboot(const evpp::TCPConnPtr& conn, const std::string& mac)
{uint64_t traceid = AKCS::Singleton<AKCS::SnowflakeIdWorker>::instance().getId();//发送REMOTE_CONTROL消息SOCKET_MSG_REMOTE_CONTROL remoteControlMsg;memset(&remoteControlMsg, 0, sizeof(SOCKET_MSG_REMOTE_CONTROL));strncpy(remoteControlMsg.szProtocal, PROTOCAL_NAME_DEFAULT, sizeof(remoteControlMsg.szProtocal) - 1);strncpy(remoteControlMsg.szType, SOCKET_MSG_TYPE_NAME_REBOOT, sizeof(remoteControlMsg.szType) - 1);::snprintf(remoteControlMsg.szItem[0], sizeof(remoteControlMsg.szItem[0]), "%d", traceid);
}

修改为”%” PRId64,代码如下:

int CDeviceControl::SendRequestReboot(const evpp::TCPConnPtr& conn, const std::string& mac)
{uint64_t traceid = AKCS::Singleton<AKCS::SnowflakeIdWorker>::instance().getId();//发送REMOTE_CONTROL消息SOCKET_MSG_REMOTE_CONTROL remoteControlMsg;memset(&remoteControlMsg, 0, sizeof(SOCKET_MSG_REMOTE_CONTROL));strncpy(remoteControlMsg.szProtocal, PROTOCAL_NAME_DEFAULT, sizeof(remoteControlMsg.szProtocal) - 1);strncpy(remoteControlMsg.szType, SOCKET_MSG_TYPE_NAME_REBOOT, sizeof(remoteControlMsg.szType) - 1);::snprintf(remoteControlMsg.szItem[0], sizeof(remoteControlMsg.szItem[0]), "%" PRId64, traceid);
}

8.warning: #warning This file includes at least one deprecated or antiquated header which may be removed without further notice at a future date.

比如代码:

In file included from /usr/include/c++/4.8/ext/hash_map:60:0, from /root/.jenkins/workspace/akcs_csmain_v5.4.0.0/csmain/build/../../csbase/redis/ostype.h:39, from /root/.jenkins/workspace/akcs_csmain_v5.4.0.0/csmain/build/../../csbase/redis/ThreadPool.h:9, from /root/.jenkins/workspace/akcs_csmain_v5.4.0.0/csmain/build/../../csbase/redis/CachePool.h:13, from AKCSServerMain.cpp:32:

修改方法cppflag增加-Wno-deprecated,当然最好的方法是找到过时的头文件,并修改掉。

9.warning: operation on ‘pC’ may be undefined [-Wsequence-point]

比较少见,问题出现在以下代码:

for (int k = 0; k < nPixelSize; ++k)
{*tmp++ = (unsigned char)(int)((B * N * (*pA++ - *pB - *pC + *pD) + dw * N * *pB+++ dh * B * *pC++ + (dw * dh - dh * B - dw * N) * *pD+++ dw * dh / 2) / (dw * dh));
}

修改方法:

for (int k = 0; k < nPixelSize; ++k)
{*tmp++ = (unsigned char)(int)((B * N * (*pA - *pB - *pC + *pD) + dw * N * *pB+ dh * B * *pC + (dw * dh - dh * B - dw * N) * *pD+ dw * dh / 2) / (dw * dh));pA++;pB++;pC++;pD++;
}

CMakefile写的不好带来的Warning

1.Policy CMP0015 is not set: link_directories() treats paths relative to the source dir

比如csroute的CMakeLists.txt

CMAKE_MINIMUM_REQUIRED(VERSION 2.8)project (route C CXX)
SET(DEPENDENT_LIBRARIES libcsbase.a pthread libhiredis.a libevent.so libglog.so libmysqlclient.so libevpp.so libevnsq.so libprotobuf.so libetcd-cpp-api.so libcpprest.so libboost_system.so libssl.so libcrypto.so libgpr.so libgrpc.so libgrpc++.so libcppkafka.solibrdkafka.so librdkafka++.so libz.so libdl.so)
LINK_DIRECTORIES(../csbase ../csbase/thirdlib ../csbase/redis/hiredis ../csbase/evpp/lib /usr/local/lib)AUX_SOURCE_DIRECTORY(./ SRC_LIST_ROUTE)
AUX_SOURCE_DIRECTORY(./dao SRC_LIST_ROUTE_DAO)
AUX_SOURCE_DIRECTORY(../csbase/encrypt SRC_LIST_BASE_ENCRYPT)
AUX_SOURCE_DIRECTORY(../csbase/Rldb SRC_LIST_BASE_RLDB)
AUX_SOURCE_DIRECTORY(../csbase/redis SRC_LIST_BASE_REDIS)
AUX_SOURCE_DIRECTORY(../csbase/protobuf SRC_LIST_BASE_PROTOBUF)
AUX_SOURCE_DIRECTORY(../csbase/etcd SRC_LIST_BASE_ETCD)
AUX_SOURCE_DIRECTORY(../csbase/grpc SRC_LIST_BASE_GRPC)
AUX_SOURCE_DIRECTORY(../csbase/grpc/cssession SRC_LIST_BASE_GRPC_SESSION)
AUX_SOURCE_DIRECTORY(../csbase/session SRC_LIST_BASE_SESSION)
AUX_SOURCE_DIRECTORY(../csbase/redis SRC_LIST_BASE_REDIS)
AUX_SOURCE_DIRECTORY(../csbase/jsoncpp0.5/src/json SRC_LIST_BASE_JSONCPP)
SET(BASE_LIST_INC ../csbase ../csbase/mysql/include ../csbase/Rldb ../csbase/evpp ../csbase/protobuf ../csbase/etcd ../csbase/session ../csbase/grpc/cssession ../csbase/redis ../csbase/grpc ../csbase/jsoncpp0.5/include ../csbae/encrypt ../csbase/grpc/gens)ADD_DEFINITIONS( -std=c++11 -g -W -Wall -D_REENTRANT -D_FILE_OFFSET_BITS=64 -DAC_HAS_INFO
-DAC_HAS_WARNING -DAC_HAS_ERROR -DAC_HAS_CRITICAL -DTIXML_USE_STL -DAC_HAS_DEBUG -DLINUX_DAEMON
-DCARES_STATICLIB -DGFLAGS_IS_A_DLL=0 -DPB_FIELD_16BIT -D_TURN_OFF_PLATFORM_STRING -Wno-unused-parameter)include_directories( ${BASE_LIST_INC} ./dao)add_executable(csroute ${SRC_LIST_ROUTE} ${SRC_LIST_ROUTE_DAO} ${SRC_LIST_BASE_ENCRYPT} ${SRC_LIST_BASE_RLDB} ${SRC_LIST_BASE_REDIS} ${SRC_LIST_BASE_PROTOBUF} ${SRC_LIST_BASE_ETCD} ${SRC_LIST_BASE_SESSION} ${SRC_LIST_BASE_GRPC_SESSION} ${SRC_LIST_BASE_REDIS} ${SRC_LIST_BASE_GRPC} ${SRC_LIST_BASE_JSONCPP})
target_link_libraries(csroute  ${DEPENDENT_LIBRARIES})

修改方法,使用变量${CMAKE_CURRENT_SOURCE_DIR},这个变量的意思是CMakeLists.txt的所在目录

CMAKE_MINIMUM_REQUIRED(VERSION 2.8)project (route C CXX)
SET(DEPENDENT_LIBRARIES libcsbase.a pthread libhiredis.a libevent.so libglog.so libmysqlclient.so libevpp.so libevnsq.so libprotobuf.so libetcd-cpp-api.so libcpprest.so libboost_system.so libssl.so libcrypto.so libgpr.so libgrpc.so libgrpc++.so libcppkafka.solibrdkafka.so librdkafka++.so libz.so libdl.so)
SET(BASE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../)
LINK_DIRECTORIES(${BASE_SOURCE_DIR}/csbase ${BASE_SOURCE_DIR}/csbase/thirdlib ${BASE_SOURCE_DIR}/csbase/redis/hiredis ${BASE_SOURCE_DIR}/csbase/evpp/lib /usr/local/lib)AUX_SOURCE_DIRECTORY(./ SRC_LIST_ROUTE)
AUX_SOURCE_DIRECTORY(./dao SRC_LIST_ROUTE_DAO)
AUX_SOURCE_DIRECTORY(../csbase/encrypt SRC_LIST_BASE_ENCRYPT)
AUX_SOURCE_DIRECTORY(../csbase/Rldb SRC_LIST_BASE_RLDB)
AUX_SOURCE_DIRECTORY(../csbase/redis SRC_LIST_BASE_REDIS)
AUX_SOURCE_DIRECTORY(../csbase/protobuf SRC_LIST_BASE_PROTOBUF)
AUX_SOURCE_DIRECTORY(../csbase/etcd SRC_LIST_BASE_ETCD)
AUX_SOURCE_DIRECTORY(../csbase/grpc SRC_LIST_BASE_GRPC)
AUX_SOURCE_DIRECTORY(../csbase/grpc/cssession SRC_LIST_BASE_GRPC_SESSION)
AUX_SOURCE_DIRECTORY(../csbase/session SRC_LIST_BASE_SESSION)
AUX_SOURCE_DIRECTORY(../csbase/redis SRC_LIST_BASE_REDIS)
AUX_SOURCE_DIRECTORY(../csbase/jsoncpp0.5/src/json SRC_LIST_BASE_JSONCPP)
SET(BASE_LIST_INC ${BASE_SOURCE_DIR}/csbase ${BASE_SOURCE_DIR}/csbase/mysql/include ${BASE_SOURCE_DIR}/csbase/Rldb ${BASE_SOURCE_DIR}/csbase/evpp ${BASE_SOURCE_DIR}/csbase/protobuf ${BASE_SOURCE_DIR}/csbase/etcd ${BASE_SOURCE_DIR}/csbase/session ${BASE_SOURCE_DIR}/csbase/grpc/cssession ${BASE_SOURCE_DIR}/csbase/redis ${BASE_SOURCE_DIR}/csbase/grpc ${BASE_SOURCE_DIR}/csbase/jsoncpp0.5/include ${BASE_SOURCE_DIR}/csbae/encrypt ${BASE_SOURCE_DIR}/csbase/grpc/gens)ADD_DEFINITIONS( -std=c++11 -g -W -Wall -D_REENTRANT -D_FILE_OFFSET_BITS=64 -DAC_HAS_INFO
-DAC_HAS_WARNING -DAC_HAS_ERROR -DAC_HAS_CRITICAL -DTIXML_USE_STL -DAC_HAS_DEBUG -DLINUX_DAEMON
-DCARES_STATICLIB -DGFLAGS_IS_A_DLL=0 -DPB_FIELD_16BIT -D_TURN_OFF_PLATFORM_STRING -Wno-unused-parameter -Wno-deprecated)include_directories( ${BASE_LIST_INC} ./dao)add_executable(csroute ${SRC_LIST_ROUTE} ${SRC_LIST_ROUTE_DAO} ${SRC_LIST_BASE_ENCRYPT} ${SRC_LIST_BASE_RLDB} ${SRC_LIST_BASE_REDIS} ${SRC_LIST_BASE_PROTOBUF} ${SRC_LIST_BASE_ETCD} ${SRC_LIST_BASE_SESSION} ${SRC_LIST_BASE_GRPC_SESSION} ${SRC_LIST_BASE_REDIS} ${SRC_LIST_BASE_GRPC} ${SRC_LIST_BASE_JSONCPP})
target_link_libraries(csroute  ${DEPENDENT_LIBRARIES})

2.Policy CMP0037 is not set: Target names should not be reserved and should match a validity pattern

比如cspdu2kafkamq的CMakeLists.txt,就会出现这个Warning

CMAKE_MINIMUM_REQUIRED(VERSION 2.8)project (cspdu2kafkamq  CXX)
SET(CSBASE_DIR ../csbase)
SET(DEPENDENT_LIBRARIES libcsbase.a pthread libglog.so libmysqlclient.so libcppkafka.a librdkafka++.a librdkafka.a libdl.so libz.so libcrypto.so libssl.so 
libevpp.so libevnsq.so libglog.so libprotobuf.so)AUX_SOURCE_DIRECTORY(./src SRC_LIST_PRODUCER)
AUX_SOURCE_DIRECTORY(${CSBASE_DIR}/Rldb SRC_LIST_DB)
AUX_SOURCE_DIRECTORY(${CSBASE_DIR}/nsq SRC_LIST_NSQ)link_directories(${CMAKE_CURRENT_SOURCE_DIR}/${CSBASE_DIR} 
${CMAKE_CURRENT_SOURCE_DIR}/${CSBASE_DIR}/thirdlib 
${CMAKE_CURRENT_SOURCE_DIR}/${CSBASE_DIR}/redis/hiredis 
${CMAKE_CURRENT_SOURCE_DIR}/${CSBASE_DIR}/evpp/lib /usr/local/lib)SET(BASE_LIST_INC ${CSBASE_DIR} ${CSBASE_DIR}/mysql/include ${CSBASE_DIR}/Rldb  ${CSBASE_DIR}/librdkafka ${CSBASE_DIR}/cppkafka
${CSBASE_DIR}/nsq ${CSBASE_DIR}/evpp)ADD_DEFINITIONS( -std=c++11 -g -W -Wall -Wno-unused-parameter -D_REENTRANT -D_FILE_OFFSET_BITS=64 -DAC_HAS_INFO
-DAC_HAS_WARNING -DAC_HAS_ERROR -DAC_HAS_CRITICAL -DTIXML_USE_STL -DAC_HAS_DEBUG -DLINUX_DAEMON)include_directories( ${BASE_LIST_INC} ./src)add_executable(./bin/cspdu2kafkamq ${SRC_LIST_PRODUCER} ${SRC_LIST_DB} ${SRC_LIST_NSQ})
target_link_libraries(./bin/cspdu2kafkamq  ${DEPENDENT_LIBRARIES})

问题出在add_executable(./bin/cspdu2kafkamq,修改为

SET(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/bin)
add_executable(cspdu2kafkamq ${SRC_LIST_PRODUCER} ${SRC_LIST_DB} ${SRC_LIST_NSQ})
target_link_libraries(cspdu2kafkamq  ${DEPENDENT_LIBRARIES})

Published by

风君子

独自遨游何稽首 揭天掀地慰生平

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注