static const char * - определено, но не используется - PullRequest
8 голосов
/ 29 ноября 2011

Нам нужно определить указатель const static char в каждом заголовочном (.h) и исходном (.cpp) файле, чтобы соответствовать стандартам кодирования компании.

static const char * one_time_param = "ABCDEFG";

При компиляции компилятор генерирует множество «определенных, но не используемых» предупреждений.У кого-нибудь есть решение этой проблемы, пожалуйста?

-Wno-unused-parameter

Используя приведенный выше флаг компилятора, мы можем подавить эти предупреждения.Но это также подавляет некоторые другие неиспользуемые параметры, которые могут потребовать внимания.Мы попробовали эти решения, которые работают только для параметров функции.

Q_UNUSED

в Qt и

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

Предыдущий вопрос аналогичного вида:

Как можноЯ скрываю "определенные, но не используемые" предупреждения в GCC?

Ответы [ 8 ]

18 голосов
/ 14 декабря 2012

В этом случае это обычно тоже указатель на константу, поэтому попробуйте использовать:

static const char * const one_time_param = "ABCDEFG";
11 голосов
/ 29 ноября 2011

Во-первых, стандарты кодирования компании, возможно, тратят впустую пространство.Если вы собираетесь это сделать, то вместо массива 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
    

Old-style

Это полный (иочень полезная) программа, иллюстрирующая старый стиль ведения бизнеса.

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

Примечание: при компиляции строка версии не включается в двоичный файл (или объектный файл).В настоящее время это не дает мне никакого предупреждения при компиляции с GCC 4.6.1, скомпилированной в MacOS X 10.7.2:

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

Когда я запускаю what al, я не получаю идентификационный вывод.

5 голосов
/ 29 ноября 2011

Взгляните на __attribute__((used)).

1 голос
/ 29 ноября 2011

Будет ли на переменную когда-либо ссылаться какая-либо внешняя утилита, проверяющая исполняемый файл, или это просто то, что вы должны иметь в источнике?

Если вам просто нужно иметь его в исходном коде, и он не обязательно должен быть в скомпилированном исполняемом файле, почему бы не #if out:

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

Дополнительным преимуществом этого метода является то, что вам больше не нужно беспокоиться о конфликтах имен в заголовочных файлах.

0 голосов
/ 29 ноября 2011

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";

Затем включите one_time_param.h в каждый & каждый заголовок и исходный файл.

<<em> почесывает голову > это, конечно, не сработает, если вам нужно, чтобы оно было static.

0 голосов
/ 29 ноября 2011

В глобальном заголовке вашего проекта объявите такой макрос:

#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");

Кажется, работает. Что бы вы ни думали о макросах и вставке токенов, по крайней мере, с помощью макроса вы сможете найти эти вещи и избавиться от них, когда люди поймут, что они глупы.

0 голосов
/ 29 ноября 2011

Определите это в одном заголовке, определите одну встроенную функцию внутри заголовка, чтобы «получить» значение указателя, а затем включите этот заголовок, где бы вам ни понадобилось определение.

0 голосов
/ 29 ноября 2011

Вы всегда можете взломать его.Например, if (one_time_param[0] == one_time_param[0]); Минимальное вычислительное усилие, и оно должно удалить предупреждение.Вполне возможно, что эта линия будет оптимизирована для запрета, потому что она по сути бесполезна для программы.

Это зависит от того, насколько элегантным вы хотите, чтобы решение было.Возможно, кто-то может порекомендовать флаг компилятора, который избавит от предупреждения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...