static const char * - 已定义但未使用

时间:2011-11-29 14:12:22

标签: c++ qt

我们需要在每个标题(.h)和源(.cpp)文件中定义const static char指针,以符合公司编码标准。

static const char * one_time_param = "ABCDEFG";

编译时,编译器会生成大量“已定义但未使用”的警告。请问有人有解决这个问题的方法吗?

-Wno-unused-parameter

使用上面的编译器标志,我们可以抑制这些警告。但是,这也抑制了一些可能需要注意的其他未使用的参数。我们尝试了这些仅适用于功能参数的解决方案。

Q_UNUSED
在Qt中

#define UNUSED(x) ((void)(x))

以前类似的问题:

How can I hide "defined but not used" warnings in GCC?

8 个答案:

答案 0 :(得分:18)

在这种情况下,它通常也是const指针, 所以尝试使用:

static const char * const one_time_param = "ABCDEFG";

答案 1 :(得分:11)

首先 - 公司编码标准可以说是浪费空间。如果您要这样做,那么使用数组而不是char *,这样您只存储数据而不是指针和数据:

static const char one_time_param[] = "ABCDEFG";

接下来,大概这是用于文件识别 - 至少,这是我使用它。有许多事情需要注意,从多年的经验中吸取教训。 (我仍然希望在源文件中嵌入版本号 - 由于这个原因,我没有全心全意地转移到DVCS。)

  1. 要避免警告,您必须在文件外部显示符号。
  2. 反过来,这意味着您必须使变量名称唯一。
  3. 我目前正在使用基于文件名的名称:jlss_id_filename_c[]等。

    #ifndef lint
    /* Prevent over-aggressive optimizers from eliminating ID string */
    const char jlss_id_errno_c[] = "@(#)$Id: errno.c,v 3.3 2011/09/07 22:33:45 jleffler Exp $";
    #endif /* lint */
    
  4. AT& T SVR4 C编译器和支持软件支持#ident指令:

    #ident "@(#)$Id: errno.c,v 3.3 2011/09/07 22:33:45 jleffler Exp $"
    

    编译器在对象文件的“注释”部分中包含字符串,并使用工具(mcs)来操作注释部分(选项-d以删除它和-c压缩它,IIRC)。此部分是二进制文件的一部分,但未在运行时加载到内存中。

  5. 在GCC演变的某一点,结合我使用的命令行选项,我收到警告,除非我声明和定义变量,所以我的'模板'为新源文件生成:

    #ifndef lint
    /* Prevent over-aggressive optimizers from eliminating ID string */
    extern const char jlss_id_filename_c[];
    const char jlss_id_filename_c[] = "@(#)$Id$";
    #endif /* lint */
    

    但是,我这些天通常会删除声明,并且不会收到编译器警告。

  6. 作为使用文件名作为变量名称基础的替代方法,您可以生成十六进制的UUID或GUID名称并将其用作变量名称,并使用前缀以确保第一个字符是字母。

  7. 在标题中,您不希望在包含标题的每个源文件中定义该材料,因为(a)它成为程序大小的显着(但不一定重要)开销,并且(b)您可以不要多次定义全局变量(你可以多次声明它们;这不是问题)。所以,我的标题有一个像:

    的节
    #ifdef MAIN_PROGRAM
    #ifndef lint
    /* Prevent over-aggressive optimizers from eliminating ID string */
    const char jlss_id_stderr_h[] = "@(#)$Id: stderr.h,v 10.3 2011/11/28 04:49:24 jleffler Exp $";
    #endif /* lint */
    #endif
    

    然后,当我想要标题来定义值时,我在相应的源文件的顶部有#define MAIN_PROGRAM。例如,通过在该名称的程序上运行what errno,我得到输出:

    errno:
    $Id: errno.c,v 3.3 2011/09/07 22:33:45 jleffler Exp $
    $Id: range.h,v 1.8 2008/02/11 07:39:36 jleffler Exp $
    $Id: stderr.h,v 10.3 2011/11/28 04:49:24 jleffler Exp $
    $Id: errhelp.c,v 8.5 2009/03/02 19:13:51 jleffler Exp $
    $Id: range2.c,v 1.8 2008/02/11 08:44:50 jleffler Exp $
    $Id: stderr.c,v 10.7 2011/11/28 04:49:24 jleffler Exp $
    stderr.c configured with USE_STDERR_FILEDESC
    stderr.c configured with USE_STDERR_SYSLOG
    
  8. 旧式

    这是一个完整的(非常有用的)程序,说明了旧式的做生意。

    /*
    @(#)File:            $RCSfile: al.c,v $
    @(#)Version:         $Revision: 1.4 $
    @(#)Last changed:    $Date: 1996/08/13 11:14:15 $
    @(#)Purpose:         List arguments one per line
    @(#)Author:          J Leffler
    @(#)Copyright:       (C) JLSS 1992,1996
    @(#)Product:         :PRODUCT:
    */
    
    /*TABSTOP=4*/
    
    #include <stdio.h>
    #include <stdlib.h>
    
    #ifndef lint
    static const char sccs[] = "@(#)$Id: al.c,v 1.4 1996/08/13 11:14:15 johnl Exp $";
    #endif
    
    int main(int argc, char **argv)  
    { 
        while (*++argv) 
            puts(*argv);
        return(EXIT_SUCCESS); 
    }
    

    注意:编译时,版本字符串不包含在二进制文件(或目标文件)中。当使用在MacOS X 10.7.2上编译的GCC 4.6.1进行编译时,这当前不会给我任何警告:

    gcc -m64 -g -O -std=c99 -pedantic -Wall -Wshadow -Wpointer-arith -Wcast-qual \
        -Wstrict-prototypes -Wmissing-prototypes -o al al.c
    

    当我运行what al时,我没有识别输出。

答案 2 :(得分:5)

答案 3 :(得分:1)

变量是否会被检查可执行文件的某个外部实用程序引用,或者它只是源中必须包含的内容?

如果您必须在源代码中拥有它,并且它不必在已编译的可执行文件中,为什么不#if它出来:

#if 0
static const char * one_time_param = "ABCDEFG";
#endif

此方法的另一个好处是您不再需要担心头文件中的名称冲突。

答案 4 :(得分:0)

你总是可以乱搞它。例如if (one_time_param[0] == one_time_param[0]); 最小的计算工作量,它应该删除警告。该行可能会针对无操作进行优化,因为它对程序本身无用。

这取决于您希望解决方案的优雅程度。也许有人可以推荐一个能够摆脱警告的编译器标志。

答案 5 :(得分:0)

在单个标题中定义它,在标题内定义一个内联函数以“获取”指针的值,然后在需要定义的任何位置包含此标题。

答案 6 :(得分:0)

在项目的全局标题中声明一个宏,如:

#define DECLARE_ONETIME_CONST(name,value) \
    static const char* name = (value); \
    static const char nowarning_##name = name[0];

然后在你的文件中说:

DECLARE_ONETIME_CONST(one_time_param, "ABCDEFG");

似乎工作。无论人们如何看待宏和令牌粘贴,至少有一个宏,你将能够找到这些东西,并在人们意识到它们是愚蠢的时候摆脱它们。 &LT;耸肩&GT;

答案 7 :(得分:0)

one_time_param.h

#ifndef ONE_TIME_PARAM_H
#define ONE_TIME_PARAM_H

extern const char* one_time_param;

#endif

one_time_param.cpp

#include "one_time_param.h"

const char* one_time_param = "ABCDEFG";

然后在每个&amp;中包含one_time_param.h。每个标题和源文件。

&lt; 划伤头&gt;如果你需要它static,这当然是行不通的。