Я не понимаю, то ли я криворук, то ли лыжи не скачут.
Файл C.h
#ifndef C_H
#define C_H
int QWE = 1;
#endif /* C_H */
Файл B.h
#include "C.h"
Файл A.h
#include "B.h"
Почему компилятор ругается на LNK2005 "int QWE" (?QWE@@3HA) уже определен в A.obj, если были использованы ifndef, define, endif?
Пробовал качать другую версию MSVS, пробовал писать #pragma once
, но ошибка остаётся. Ткните носом, где я туплю?
Вы подключаете (пусть опосредованно) c.h
в разные .cpp
-файлы, вот у вас и получается в двух разных файлах определение
int QWE = 1;
Вот линковщик и ругается, встречая две переменные с одним именем в двух разных местах, не зная, что ему выбрать...
Объявите переменную в .h
-файле как
extern int QWE;
а в одном .cpp
-файле определите
int QWE = 1;
Так вы перестанете нарушать правило одного определения.
Назначение include guards #ifndef/#define/#endif
- защитить ваш код от ошибок вида
#include "C.h"
...
#include "C.h"
т.е. от множественного включения одного и того же заголовка в одну и ту же единицу трансляции (явно или опосредованно, через другие заголовки). Такое множественное включение в общем случае приведет к ошибкам компиляции.
Include guards, вопреки вашим ожиданиям, не имеют никакого отношения к защите от ошибок множественного определения переменных или функций во всей программе, т.е. между разными единицами трансляции (вызывающих ошибки линковки). От вашей ошибки include guards никак не защищают и не должны защищать, поэтому ваше удивление "Почему компилятор ругается на LNK2005, ... если были использованы ifndef, define, endif?" совершенно не оправданно.
Либо перестаньте совать определения переменных в заголовочный файл (т.е. пойдите по "классическому" пути с extern
). Либо воспользуйтесь свойством С++17 и просто сделайте вашу переменную inline
#ifndef C_H
#define C_H
inline int QWE = 1;
#endif /* C_H */
Виртуальный выделенный сервер (VDS) становится отличным выбором
У меня есть некий класс, который является оберткой над массивомЭтот класс называется хранилищем моих элементов
Есть программа, большую часть своей жизни она сидит в трее и должна иногда мигать иконкой, при двойном клике открывать вебкитМигает она или...
Почему вылетает приложениеНачинаю работать с sqlite, простой вывод данных бд в listView не работет - приложение просто вылетает