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

Проблема заключается в следующем, у меня есть следующая структура:

struct s_log_message{
    lll level;
    const unsigned int i;
    const char *msg;
}typedef log_message;

И следующий массив указанных структур:

const log_message logging_messages[]{
    {
        error,
        0,
        ACR "ERROR" ACS ":" "No arguments given, use -h or --help for information on how to use the program\0"
    },
    NULL
};

ACR и ACS определяют изменение цвета терминала.

Уровень lll - это перечисление:

enum log_level_list{none=0,info=1,warn=2,error=3};
typedef enum log_level_list     lll;

Весь этот код находится в 3 разных файлах:

Log.h :

#ifndef LOG
#define LOG 220

enum log_level_list{none=0,info=1,warn=2,error=3};
typedef enum log_level_list     lll;

class log{
public:
    static void                         set_log_level(lll val);
    static unsigned char        get_log_level(void);

    static void                         l(unsigned int warn_i);
private:
    log(){}

    static unsigned char        log_level;
};

#endif

Lmg.h :

#ifndef     LOG_MESSAGES
#define     LOG_MESSAGES    100
#include "../lib/log.h" //included for definition of enum type lll

struct s_log_message{
    lll level;
    const unsigned int i;
    const char *msg;
}typedef log_message;

extern const log_message logging_messages[];

#endif

И lmg.cpp:

#include "../lib/col.h"         //terminal color defines
#include "../lib/lmg.h"         //header for this file
#include <cstddef>                  //included for definition of NULL

const log_message logging_messages[]{
    {
        error,
        0,
        ACR "ERROR" ACS ":" "No arguments given, use -h or --help for information on how to use the program\0"
    },
    NULL
};

Напомним, проблема в том, что завершение массива loggin_messages [] с помощью NULL приводит к тому, что компилятор выдает следующую ошибку:

g++ -Wall -o DFHM ./src/main.cpp ./lib/lib.cpp ./lib/EasyBMP.cpp ./lib/dat.cpp ./lib/log.cpp ./lib/lmg.cpp
./lib/lmg.cpp:12:1: error: invalid conversion from ‘long int’ to ‘lll’ {aka ‘log_level_list’} [-fpermissive]
   12 | };
      | ^
      | |
      | long int
make: *** [makefile:14: main] Error 1

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

c++
0
Santiago Perotti 30 Июл 2020 в 02:14

2 ответа

Лучший ответ

NULL является константой нулевого указателя. Он предназначен для установки указателей в нулевое значение, не указывающее на что-либо.

logging_messages не содержит указатели, хотя. Это массив log_message объектов. Нет смысла инициализировать log_message в NULL.

Если вы хотите добавить «пустой» объект, который будет служить терминатором в ваш массив, вместо того, чтобы хранить размер массива отдельно, вы можете сделать это, но состояние «пустой» вашего типа зависит от вас. Например, { none, 0, nullptr } может быть вашим определенным «пустым» состоянием. Это конкретное состояние также может быть записано как просто {}, так как члены, которые не заданы в агрегатной инициализации, будут инициализированы значением.

0
Miles Budnek 29 Июл 2020 в 23:56

Вам не нужно завершать каждый вид массива с помощью NULL. На самом деле, строго говоря, даже char массивам не нужно завершаться с помощью NULL. К счастью, вы можете иметь массивы, не заканчивающиеся NULL, до тех пор, пока вы пишете свой код, чтобы вы не выходили за пределы конца массива.

Конечно, для массивов char существует установленное соглашение, согласно которому многие функции интерпретируют значение NULL char как конец полезных данных. Однако эта идея не установлена ни для какого другого типа массива.

Или, говоря иначе, NULL не является допустимым значением для struct (или class и т. Д.). Хотя это указатель на один, это совершенно другой тип. Если у вас есть фактический экземпляр объекта (например, struct), он не может быть пустым.

0
nanofarad 29 Июл 2020 в 23:34