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 want
  std::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.so
 librdkafka.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.so
 librdkafka.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})
  • 3
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值