简体   繁体   English

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

[英]static const char * - defined but not used

We need to define a const static char pointer in each and every header (.h) and source (.cpp) file to comply with company coding standards. 我们需要在每个头(.h)和源(.cpp)文件中定义一个const static char指针,以符合公司编码标准。

static const char * one_time_param = "ABCDEFG";

When compiled, the compiler is generating lot of "defined but not used" warnings. 编译时,编译器会生成大量“已定义但未使用”的警告。 Does someone have a solution to this issue, please? 请问有人有解决这个问题的方法吗?

-Wno-unused-parameter

Using the above compiler flag, we can suppress these warnings. 使用上面的编译器标志,我们可以抑制这些警告。 But, this also suppresses some other unused parameters which might need attention. 但是,这也抑制了一些可能需要注意的其他未使用的参数。 We tried these solutions which only work for function parameters. 我们尝试了这些仅适用于功能参数的解决方案。

Q_UNUSED

in Qt, and 在Qt,和

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

Previous question of similar kind: 以前的类似问题:

How can I hide "defined but not used" warnings in GCC? 如何在GCC中隐藏“已定义但未使用”的警告?

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

static const char * const one_time_param = "ABCDEFG";

First - the company coding standards are arguably wasting space. 首先 - 公司编码标准可以说是浪费空间。 If you're going to do that, then use an array instead of a char * so you store just the data and not a pointer and the data: 如果您要这样做,那么使用数组而不是char *因此您只存储数据而不是指针和数据:

static const char one_time_param[] = "ABCDEFG";

Next, presumably this is for file identification - that, at least, is what I use it for. 接下来,大概这是用于文件识别 - 至少,这是我使用它。 There are several things to be aware of, learned from experience over a number of years. 有许多事情需要注意,从多年的经验中吸取教训。 (I still like to embed version numbers in the source files - I haven't whole-heartedly moved to DVCS because of this.) (我仍然希望在源文件中嵌入版本号 - 因此我没有全心全意地转移到DVCS。)

  1. To avoid the warnings, you have to make the symbols visible outside the file. 要避免警告,您必须在文件外部显示符号。
  2. That, in turn, means you have to make the variable names unique. 反过来,这意味着您必须使变量名称唯一。
  3. I'm currently using names based on file name: jlss_id_filename_c[] etc. 我目前正在使用基于文件名的名称: 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. The AT&T SVR4 C compiler and support software supported a #ident directive: AT&T SVR4 C编译器和支持软件支持#ident指令:

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

    The compiler included the strings in a 'comments' section in the object file, and a tool ( mcs ) to manipulate the comments section (options -d to delete it and -c to compress it, IIRC). 编译器将字符串包含在目标文件的“注释”部分中,并使用工具( mcs )来操作注释部分(选项-d将其删除, -c将其压缩,IIRC)。 This section was part of the binary, but not loaded into memory at runtime. 此部分是二进制文件的一部分,但未在运行时加载到内存中。

  5. At one point in GCC's evolution, in conjunction with the command line options I was using, I got warnings unless I declared as well as defined the variable, so my 'template' for new source file generates: 在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 */ 

    However, I normally remove the declaration these days, and don't get compiler warnings. 但是,我这些天通常会删除声明,并且不会收到编译器警告。

  6. As an alternative to using the file name as the basis of variable name, you could generate a UUID or GUID name in hex and use that as the variable name, with a prefix to ensure the first character is alphabetic. 作为使用文件名作为变量名称基础的替代方法,您可以生成十六进制的UUID或GUID名称并将其用作变量名称,并使用前缀以确保第一个字符是字母。

  7. In headers, you don't want that material defined in every source file that includes the header because (a) it becomes a noticable (but not necessarily significant) overhead on program size, and (b) you can't multiply define global variables (you can multiply declare them; that's not a problem). 在标题中,您不希望在包含标题的每个源文件中定义该材料,因为(a)它成为程序大小的显着(但不一定是重要的)开销,并且(b)您不能多次定义全局变量(你可以多次声明它们;这不是问题)。 So, my headers have a stanza like: 所以,我的标题有一个像:

     #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 

    Then, when I want the headers to define the values, I have #define MAIN_PROGRAM at the top of the corresponding source file. 然后,当我想要标题来定义值时,我在相应的源文件的顶部有#define MAIN_PROGRAM For example, from running what errno on a program of that name, I get the output: 例如,通过在该名称的程序上运行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 

Old-style 老式

This is a complete (and very useful) program illustrating the old-style of doing business. 这是一个完整的(非常有用的)程序,说明了旧式的业务。

/*
@(#)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); 
}

NB: When that is compiled, the version string is not included in the binary (or the object file). 注意:编译时,版本字符串不包含在二进制文件(或目标文件)中。 This does not currently give me any warning when compiled with GCC 4.6.1 compiled on MacOS X 10.7.2: 当使用在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

When I run what al , I get no identification output. 当我运行what al ,我没有识别输出。

看一下__attribute__((used))

Will the variable ever be referenced by some external utility examining the executable, or is it just something you must have in the source? 变量是否会被检查可执行文件的某个外部实用程序引用,或者它只是源中必须具有的内容?

If you just must have it in the source, and it doesn't have to be in the compiled executable, why not #if it out: 如果你必须在源代码中拥有它,并且它不必在编译的可执行文件中,为什么不#if it out:

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

The added benefit of this method is that you no longer have to worry about name clashes in the header files. 此方法的额外好处是您不再需要担心头文件中的名称冲突。

You could always hack around it. 你总是可以破解它。 eg if (one_time_param[0] == one_time_param[0]); 例如if (one_time_param[0] == one_time_param[0]); Minimal computational effort and it should remove the warning. 最小的计算工作量,它应该删除警告。 It's possible that that line would be optimised to a no-op because it's inherently useless to the program. 该行可能会针对无操作进行优化,因为它对程序本身无用。

It depends on how elegant you want the solution to be. 这取决于您希望解决方案的优雅程度。 Perhaps somebody can recommend a compiler flag that'll get rid of the warning. 也许有人可以推荐一个能够摆脱警告的编译器标志。

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

In a global header for your project declare a macro like: 在项目的全局标题中声明一个宏,如:

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

Then in your files say: 然后在你的文件中说:

DECLARE_ONETIME_CONST(one_time_param, "ABCDEFG");

Seems to work. 似乎工作。 Whatever one might think about macros and token pasting, at least with a macro you'll be able to find these things and get rid of them when people realize they're silly. 无论人们如何看待宏和令牌粘贴,至少有一个宏,你将能够找到这些东西,并在人们意识到它们是愚蠢的时候摆脱它们。 <shrugs> <耸肩>

one_time_param.h 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 one_time_param.cpp

#include "one_time_param.h"

const char* one_time_param = "ABCDEFG";

Then include one_time_param.h in each & every header and source file. 然后在每个头文件和源文件中包含one_time_param.h。

< scrathes head > this of course won't work if you need it to be static . < scratchhes head >如果你需要它是static这当然是行不通的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM