Ошибка компиляции Β«β€˜i’ was not declared in this scopeΒ»** β€” ΠΎΠ΄Π½Π° ΠΈΠ· самых распространённых ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ, с ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌΠΈ ΡΡ‚Π°Π»ΠΊΠΈΠ²Π°ΡŽΡ‚ΡΡ программисты Π½Π° C++, особСнно Π½ΠΎΠ²ΠΈΡ‡ΠΊΠΈ. Она ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ компилятор Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π½Π°ΠΉΡ‚ΠΈ объявлСниС ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ, Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈΠ»ΠΈ Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Π° Π² Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ области видимости. На ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ взгляд ошибка каТСтся Ρ‚Ρ€ΠΈΠ²ΠΈΠ°Π»ΡŒΠ½ΠΎΠΉ, Π½ΠΎ Π΅Ρ‘ ΠΏΡ€ΠΈΡ‡ΠΈΠ½Ρ‹ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ самыми Ρ€Π°Π·Π½Ρ‹ΠΌΠΈ: ΠΎΡ‚ ΠΎΠΏΠ΅Ρ‡Π°Ρ‚ΠΊΠΈ Π² ΠΈΠΌΠ΅Π½ΠΈ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ Π΄ΠΎ Π½Π΅ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎΠΉ ΠΎΡ€Π³Π°Π½ΠΈΠ·Π°Ρ†ΠΈΠΈ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½Ρ‹Ρ… Ρ„Π°ΠΉΠ»ΠΎΠ².

Π’ этой ΡΡ‚Π°Ρ‚ΡŒΠ΅ ΠΌΡ‹ Π΄Π΅Ρ‚Π°Π»ΡŒΠ½ΠΎ Ρ€Π°Π·Π±Π΅Ρ€Ρ‘ΠΌ всС Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Π΅ сцСнарии возникновСния ошибки, продСмонстрируСм Ρ‚ΠΈΠΏΠΈΡ‡Π½Ρ‹Π΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ ΠΊΠΎΠ΄Π° с Π±Π°Π³Π°ΠΌΠΈ, Π° Ρ‚Π°ΠΊΠΆΠ΅ прСдоставим Ρ‡Π΅ΠΊ-листы ΠΈ практичСскиС Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΠΈ ΠΏΠΎ ΠΈΡΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΡŽ. ОсобоС Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ ΡƒΠ΄Π΅Π»ΠΈΠΌ нюансам Ρ€Π°Π±ΠΎΡ‚Ρ‹ с пространствами ΠΈΠΌΡ‘Π½, Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½Ρ‹ΠΌΠΈ Ρ„Π°ΠΉΠ»Π°ΠΌΠΈ ΠΈ областями видимости, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ часто становятся источником ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹. Если Π²Ρ‹ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½Π°Ρ‡ΠΈΠ½Π°Π΅Ρ‚Π΅ ΠΎΡΠ²Π°ΠΈΠ²Π°Ρ‚ΡŒ C++ ΠΈΠ»ΠΈ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ ΡΠΈΡΡ‚Π΅ΠΌΠ°Ρ‚ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ знания β€” этот ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π» Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠΎΠ»Π΅Π·Π΅Π½.

Π§Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚ ошибка Β«was not declared in this scopeΒ»?

Π‘ΠΎΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅ ΠΎΠ± ошибкС β€˜identifier’ was not declared in this scope гСнСрируСтся компилятором GCC, Clang ΠΈΠ»ΠΈ MSVC, ΠΊΠΎΠ³Π΄Π° ΠΎΠ½ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π½Π°ΠΉΡ‚ΠΈ объявлСниС ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Π° (ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ, Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, класса ΠΈ Ρ‚.Π΄.) Π² Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ области видимости. Π’Π°ΠΆΠ½ΠΎ ΠΏΠΎΠ½ΠΈΠΌΠ°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΎΠ±Π»Π°ΡΡ‚ΡŒ видимости (scope) Π² C++ опрСдСляСтся:

  • πŸ”Ή Π€ΠΈΠ³ΡƒΡ€Π½Ρ‹ΠΌΠΈ скобками {} β€” ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡ΠΈΠ²Π°ΡŽΡ‚ Π±Π»ΠΎΠΊ ΠΊΠΎΠ΄Π° (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Ρ‚Π΅Π»ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈΠ»ΠΈ Ρ†ΠΈΠΊΠ»Π°).
  • πŸ”Ή ΠŸΡ€ΠΎΡΡ‚Ρ€Π°Π½ΡΡ‚Π²Π°ΠΌΠΈ ΠΈΠΌΡ‘Π½ (namespace) β€” ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ Π³Ρ€ΡƒΠΏΠΏΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Ρ‹.
  • πŸ”Ή Классами/структурами β€” ΠΈΡ… Ρ‡Π»Π΅Π½Ρ‹ ΠΈΠΌΠ΅ΡŽΡ‚ ΡΠΎΠ±ΡΡ‚Π²Π΅Π½Π½ΡƒΡŽ ΠΎΠ±Π»Π°ΡΡ‚ΡŒ видимости.
  • πŸ”Ή Π€Π°ΠΉΠ»Π°ΠΌΠΈ β€” Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹Π΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π²ΠΈΠ΄Π½Ρ‹ Π²ΠΎ всём Ρ„Π°ΠΉΠ»Π΅ (Π΄ΠΎ объявлСния).

НапримСр, Ссли Π²Ρ‹ ΠΏΡ‹Ρ‚Π°Π΅Ρ‚Π΅ΡΡŒ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ i Π²Π½Π΅ Ρ†ΠΈΠΊΠ»Π° for, Π³Π΄Π΅ ΠΎΠ½Π° Π±Ρ‹Π»Π° объявлСна, компилятор выдаст эту ΠΎΡˆΠΈΠ±ΠΊΡƒ. Π’ΠΎ ΠΆΠ΅ самоС ΠΏΡ€ΠΎΠΈΠ·ΠΎΠΉΠ΄Ρ‘Ρ‚, Ссли Π²Ρ‹ Π·Π°Π±ΡƒΠ΄Π΅Ρ‚Π΅ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ» с объявлСниСм Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈΠ»ΠΈ класса.

⚠️ Π’Π½ΠΈΠΌΠ°Π½ΠΈΠ΅: Ошибка ΠΌΠΎΠΆΠ΅Ρ‚ ΠΌΠ°ΡΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π±ΠΎΠ»Π΅Π΅ Π³Π»ΡƒΠ±ΠΎΠΊΠΈΠ΅ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹, Ρ‚Π°ΠΊΠΈΠ΅ ΠΊΠ°ΠΊ ΠΎΠΏΠ΅Ρ‡Π°Ρ‚ΠΊΠΈ Π² ΠΈΠΌΠ΅Π½Π°Ρ… ΠΈΠ»ΠΈ Π½Π΅ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΡƒΡŽ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½Ρ‹Ρ… Ρ„Π°ΠΉΠ»ΠΎΠ². ВсСгда провСряйтС сначала ΠΏΡ€ΠΎΡΡ‚Π΅ΠΉΡˆΠΈΠ΅ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Ρ‹!

Π’ΠΈΠΏΠΈΡ‡Π½Ρ‹Π΅ ΠΏΡ€ΠΈΡ‡ΠΈΠ½Ρ‹ ошибки ΠΈ ΠΊΠ°ΠΊ ΠΈΡ… ΠΈΡΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ

Рассмотрим Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ частыС сцСнарии, приводящиС ΠΊ ошибкС, ΠΈ способы ΠΈΡ… устранСния.

1. ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Π°Ρ объявлСна Π² Π΄Ρ€ΡƒΠ³ΠΎΠΉ области видимости

ΠšΠ»Π°ΡΡΠΈΡ‡Π΅ΡΠΊΠΈΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ β€” ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠ° ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ Ρ†ΠΈΠΊΠ»Π° for Π·Π° Π΅Π³ΠΎ ΠΏΡ€Π΅Π΄Π΅Π»Π°ΠΌΠΈ:

for (int i = 0; i < 10; i++) {

// ...

}

cout << i; // Ошибка: 'i' нС объявлСна здСсь!

Π’ C++ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅, ΠΎΠ±ΡŠΡΠ²Π»Π΅Π½Π½Ρ‹Π΅ Π² Ρ†ΠΈΠΊΠ»Π΅ for, ΠΈΠΌΠ΅ΡŽΡ‚ ΠΎΠ±Π»Π°ΡΡ‚ΡŒ видимости Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π²Π½ΡƒΡ‚Ρ€ΠΈ этого Ρ†ΠΈΠΊΠ»Π°. Π§Ρ‚ΠΎΠ±Ρ‹ ΠΈΡΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ, ΠΎΠ±ΡŠΡΠ²ΠΈΡ‚Π΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ Π΄ΠΎ Ρ†ΠΈΠΊΠ»Π°:

int i;

for (i = 0; i < 10; i++) {

// ...

}

cout << i; // Π’Π΅ΠΏΠ΅Ρ€ΡŒ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚

2. ΠžΠΏΠ΅Ρ‡Π°Ρ‚ΠΊΠ° Π² ΠΈΠΌΠ΅Π½ΠΈ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Π°

Π‘Π°Π½Π°Π»ΡŒΠ½Π°Ρ, Π½ΠΎ частая ошибка β€” ΠΎΠΏΠ΅Ρ‡Π°Ρ‚ΠΊΠ° Π² ΠΈΠΌΠ΅Π½ΠΈ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ ΠΈΠ»ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ. НапримСр:

int counter = 0;

// ...

cunter++; // Ошибка: ΠΎΠΏΠ΅Ρ‡Π°Ρ‚ΠΊΠ° Π² 'counter'

РСшСниС: Π²Π½ΠΈΠΌΠ°Ρ‚Π΅Π»ΡŒΠ½ΠΎ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅ всС вхоТдСния ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Π°. МногиС IDE (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, CLion ΠΈΠ»ΠΈ Visual Studio) ΠΏΠΎΠ΄ΡΠ²Π΅Ρ‡ΠΈΠ²Π°ΡŽΡ‚ Π½Π΅ΠΎΠΏΡ€Π΅Π΄Π΅Π»Ρ‘Π½Π½Ρ‹Π΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅.

3. ΠžΡ‚ΡΡƒΡ‚ΡΡ‚Π²ΡƒΠ΅Ρ‚ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½ΠΎΠ³ΠΎ Ρ„Π°ΠΉΠ»Π°

Если Π²Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ ΠΈΠ»ΠΈ класс ΠΈΠ· стандартной Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, std::vector), Π½ΠΎ Π·Π°Π±Ρ‹Π»ΠΈ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ Ρ…Π΅Π΄Π΅Ρ€, компилятор Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Π·Π½Π°Ρ‚ΡŒ ΠΎ ΠΈΡ… сущСствовании:

#include 

// Π—Π°Π±Ρ‹Π»ΠΈ #include

std::vector data; // Ошибка: 'vector' нС объявлСн

РСшСниС: Π΄ΠΎΠ±Π°Π²ΡŒΡ‚Π΅ Π½Π΅Π΄ΠΎΡΡ‚Π°ΡŽΡ‰ΠΈΠΉ #include. Для стандартных ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ΠΎΠ² это ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ <vector>, <map>, <string> ΠΈ Ρ‚.Π΄.

4. ΠΠ΅ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎΠ΅ использованиС пространств ΠΈΠΌΡ‘Π½

Если ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ объявлСн Π² пространствС ΠΈΠΌΡ‘Π½ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, std), Π½ΠΎ Π²Ρ‹ Π½Π΅ ΡƒΠΊΠ°Π·Π°Π»ΠΈ Π΅Π³ΠΎ явно ΠΈΠ»ΠΈ Π½Π΅ Π΄ΠΎΠ±Π°Π²ΠΈΠ»ΠΈ using, компилятор Π½Π΅ смоТСт Π΅Π³ΠΎ Π½Π°ΠΉΡ‚ΠΈ:

#include 

int main() {

cout << "Hello"; // Ошибка: 'cout' Π½Π΅ объявлСн (Π½ΡƒΠΆΠ½ΠΎ std::cout)

return 0;

}

РСшСния:

  • πŸ”Ή Π”ΠΎΠ±Π°Π²ΡŒΡ‚Π΅ прСфикс пространства ΠΈΠΌΡ‘Π½: std::cout.
  • πŸ”Ή Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΈΠ²Ρƒ using namespace std; (Π½Π΅ рСкомСндуСтся Π² Π±ΠΎΠ»ΡŒΡˆΠΈΡ… ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°Ρ…).
  • πŸ”Ή Π”ΠΎΠ±Π°Π²ΡŒΡ‚Π΅ using std::cout; для ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠ³ΠΎ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Π°.
πŸ“Š Как часто Π²Ρ‹ ΡΡ‚Π°Π»ΠΊΠΈΠ²Π°Π΅Ρ‚Π΅ΡΡŒ с ошибками компиляции Π² C++?
  • Π•ΠΆΠ΅Π΄Π½Π΅Π²Π½ΠΎ
  • НСсколько Ρ€Π°Π· Π² нСдСлю
  • Π Π΅Π΄ΠΊΠΎ
  • Никогда

Ошибка Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½Ρ‹Ρ… Ρ„Π°ΠΉΠ»Π°Ρ…: распространённыС Π»ΠΎΠ²ΡƒΡˆΠΊΠΈ

Π Π°Π±ΠΎΡ‚Π° с Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½Ρ‹ΠΌΠΈ Ρ„Π°ΠΉΠ»Π°ΠΌΠΈ (.h ΠΈΠ»ΠΈ .hpp) часто становится источником ошибок Β«was not declared in this scopeΒ»**. Рассмотрим Ρ‚ΠΈΠΏΠΈΡ‡Π½Ρ‹Π΅ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹.

1. ΠžΡ‚ΡΡƒΡ‚ΡΡ‚Π²ΡƒΠ΅Ρ‚ ΠΎΡ…Ρ€Π°Π½Π° ΠΎΡ‚ ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎΠ³ΠΎ Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ

Если Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ» ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ нСсколько Ρ€Π°Π· (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Ρ‡Π΅Ρ€Π΅Π· Ρ†Π΅ΠΏΠΎΡ‡ΠΊΡƒ Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ), компилятор ΠΌΠΎΠΆΠ΅Ρ‚ Π²Ρ‹Π΄Π°Π²Π°Ρ‚ΡŒ ошибки ΠΎ ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎΠΌ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠΈ. РСшСниС β€” ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ include guards:

// myheader.hpp

#ifndef MYHEADER_HPP

#define MYHEADER_HPP

// Π’Π°Ρˆ ΠΊΠΎΠ΄ здСсь

#endif // MYHEADER_HPP

Π’ соврСмСнном C++ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π±ΠΎΠ»Π΅Π΅ ΠΊΠΎΡ€ΠΎΡ‚ΠΊΠΈΠΉ синтаксис:

#pragma once

// Π’Π°Ρˆ ΠΊΠΎΠ΄ здСсь

2. НСсоотвСтствиС объявлСния ΠΈ опрСдСлСния

Если Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½ΠΎΠΌ Ρ„Π°ΠΉΠ»Π΅ объявлСна функция, Π½ΠΎ Π΅Ρ‘ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ Π² .cpp Ρ„Π°ΠΉΠ»Π΅ Π½Π΅ совпадаСт ΠΏΠΎ сигнатурС, компилятор Π½Π΅ смоТСт ΡΠ²ΡΠ·Π°Ρ‚ΡŒ ΠΈΡ…:

// header.hpp

void printMessage(int x);

// source.cpp

void printMessage(float x) { // Ошибка: сигнатуры Π½Π΅ ΡΠΎΠ²ΠΏΠ°Π΄Π°ΡŽΡ‚!

std::cout << x;

}

РСшСниС: ΡƒΠ±Π΅Π΄ΠΈΡ‚Π΅ΡΡŒ, Ρ‡Ρ‚ΠΎ объявлСниС ΠΈ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ‡Π½Ρ‹ (Π²ΠΊΠ»ΡŽΡ‡Π°Ρ пространства ΠΈΠΌΡ‘Π½, ΠΌΠΎΠ΄ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Ρ‹ const ΠΈ Ρ‚.Π΄.).

3. Π—Π°Π±Ρ‹Π»ΠΈ ΡΠΊΡΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ символы ΠΈΠ· пространства ΠΈΠΌΡ‘Π½

Если функция объявлСна Π²Π½ΡƒΡ‚Ρ€ΠΈ пространства ΠΈΠΌΡ‘Π½ Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½ΠΎΠΌ Ρ„Π°ΠΉΠ»Π΅, Π½ΠΎ ΠΏΡ€ΠΈ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠΈ пространство ΠΈΠΌΡ‘Π½ Π½Π΅ ΡƒΠΊΠ°Π·Π°Π½ΠΎ, компилятор Π½Π΅ Π½Π°ΠΉΠ΄Ρ‘Ρ‚ Π΅Ρ‘:

// header.hpp

namespace utils {

void helper();

}

// source.cpp

void helper() { // Ошибка: Π½ΡƒΠΆΠ½ΠΎ utils::helper

// ...

}

Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ Π»ΠΈ include guards (#pragma once)?

Π‘ΠΎΠ²ΠΏΠ°Π΄Π°ΡŽΡ‚ Π»ΠΈ сигнатуры объявлСний ΠΈ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠΉ?

Π£ΠΊΠ°Π·Π°Π½Ρ‹ Π»ΠΈ пространства ΠΈΠΌΡ‘Π½ ΠΏΡ€ΠΈ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ?

ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½Ρ‹ Π»ΠΈ всС Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ Ρ…Π΅Π΄Π΅Ρ€Ρ‹ Π² .cpp Ρ„Π°ΠΉΠ»Π΅?

-->

ΠžΡΠΎΠ±Π΅Π½Π½ΠΎΡΡ‚ΠΈ ошибки Π² ΡˆΠ°Π±Π»ΠΎΠ½Π°Ρ… ΠΈ макросах

Π¨Π°Π±Π»ΠΎΠ½Ρ‹ (template) ΠΈ макросы (#define) Π΄ΠΎΠ±Π°Π²Π»ΡΡŽΡ‚ слоТности ΠΏΡ€ΠΈ Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½ΠΈΠΈ ΠΈΠΌΡ‘Π½. Рассмотрим ΠΊΠ»ΡŽΡ‡Π΅Π²Ρ‹Π΅ ΠΌΠΎΠΌΠ΅Π½Ρ‚Ρ‹.

1. Π¨Π°Π±Π»ΠΎΠ½Π½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈ классы

Если шаблонная функция ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π° Π² .cpp Ρ„Π°ΠΉΠ»Π΅, Π° Π½Π΅ Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½ΠΎΠΌ, компилятор Π½Π΅ смоТСт Π΅Ρ‘ Π½Π°ΠΉΡ‚ΠΈ ΠΏΡ€ΠΈ инстанцировании:

// wrong.cpp

template

void print(T value) {

std::cout << value;

}

// main.cpp

int main() {

print(42); // Ошибка: шаблон нС видСн здСсь!

return 0;

}

РСшСниС: ΠΏΠΎΠΌΠ΅Ρ‰Π°ΠΉΡ‚Π΅ опрСдСлСния шаблонов Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½Ρ‹Π΅ Ρ„Π°ΠΉΠ»Ρ‹ ΠΈΠ»ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ ΡΠ²Π½ΡƒΡŽ ΠΈΠ½ΡΡ‚Π°Π½Ρ†ΠΈΠ°Ρ†ΠΈΡŽ.

2. ΠœΠ°ΠΊΡ€ΠΎΡΡ‹ ΠΈ условная компиляция

Если ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ объявлСн Π²Π½ΡƒΡ‚Ρ€ΠΈ Π±Π»ΠΎΠΊΠ° #ifdef, Π½ΠΎ макрос Π½Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Ρ‘Π½, компилятор Π΅Π³ΠΎ Β«Π½Π΅ ΡƒΠ²ΠΈΠ΄ΠΈΡ‚Β»:

#define USE_FEATURE

int main() {

#ifdef USE_FEATURE

int featureVar = 10;

#endif

std::cout << featureVar; // Ошибка, Ссли USE_FEATURE Π½Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Ρ‘Π½!

return 0;

}

⚠️ Π’Π½ΠΈΠΌΠ°Π½ΠΈΠ΅: ΠœΠ°ΠΊΡ€ΠΎΡΡ‹ Π½Π΅ ΠΈΠΌΠ΅ΡŽΡ‚ области видимости Π² ΠΏΡ€ΠΈΠ²Ρ‹Ρ‡Π½ΠΎΠΌ смыслС! Они ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°ΡŽΡ‚ΡΡ прСпроцСссором Π΄ΠΎ компиляции, поэтому ошибки с Π½ΠΈΠΌΠΈ часто ΠΌΠ΅Π½Π΅Π΅ ΠΎΡ‡Π΅Π²ΠΈΠ΄Π½Ρ‹.

Как ΠΎΡ‚Π»Π°ΠΆΠΈΠ²Π°Ρ‚ΡŒ ΠΎΡˆΠΈΠ±ΠΊΡƒ: пошаговая инструкция

Если Π²Ρ‹ ΡΡ‚ΠΎΠ»ΠΊΠ½ΡƒΠ»ΠΈΡΡŒ с ошибкой Β«was not declared in this scopeΒ»**, слСдуйтС этому Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΡƒ:

  1. ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅ ΠΎΠΏΠ΅Ρ‡Π°Ρ‚ΠΊΠΈ. Π£Π±Π΅Π΄ΠΈΡ‚Π΅ΡΡŒ, Ρ‡Ρ‚ΠΎ имя ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Π° написано ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ Π²ΠΎ всСх мСстах.
  2. Π˜Ρ‰ΠΈΡ‚Π΅ объявлСниС. Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ поиск ΠΏΠΎ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Ρƒ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Ctrl+Shift+F Π² VS Code), Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π½Π°ΠΉΡ‚ΠΈ, Π³Π΄Π΅ пСрСмСнная ΠΈΠ»ΠΈ функция Π΄ΠΎΠ»ΠΆΠ½Π° Π±Ρ‹Ρ‚ΡŒ объявлСна.
  3. ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅ ΠΎΠ±Π»Π°ΡΡ‚ΡŒ видимости. Π£Π±Π΅Π΄ΠΈΡ‚Π΅ΡΡŒ, Ρ‡Ρ‚ΠΎ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ доступСн Π² Ρ‚ΠΎΠΌ мСстС, Π³Π΄Π΅ Π²Ρ‹ Π΅Π³ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚Π΅ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π½Π΅ Π²Π½ΡƒΡ‚Ρ€ΠΈ if ΠΈΠ»ΠΈ Ρ†ΠΈΠΊΠ»Π°).
  4. ΠšΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΡƒΠΉΡ‚Π΅ с Ρ„Π»Π°Π³ΠΎΠΌ -E. Для GCC/Clang запуститС g++ -E file.cpp, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡƒΠ²ΠΈΠ΄Π΅Ρ‚ΡŒ ΠΊΠΎΠ΄ послС прСпроцСссинга. Π­Ρ‚ΠΎ ΠΏΠΎΠΌΠΎΠΆΠ΅Ρ‚ Π²Ρ‹ΡΠ²ΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ с макросами ΠΈΠ»ΠΈ Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡΠΌΠΈ.
  5. ΠœΠΈΠ½ΠΈΠΌΠΈΠ·ΠΈΡ€ΡƒΠΉΡ‚Π΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€. Π£Π΄Π°Π»ΠΈΡ‚Π΅ лишний ΠΊΠΎΠ΄, ΠΎΡΡ‚Π°Π²ΡŒΡ‚Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‡Π°ΡΡ‚ΡŒ, Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‰ΡƒΡŽ ΠΎΡˆΠΈΠ±ΠΊΡƒ. Часто это ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ‚ Π»ΠΎΠΊΠ°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡƒ.

Если ошибка сохраняСтся, ΠΏΠΎΠΏΡ€ΠΎΠ±ΡƒΠΉΡ‚Π΅ ΠΈΠ·ΠΎΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ½Ρ‹ΠΉ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚ Π² ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠΌ Ρ„Π°ΠΉΠ»Π΅ ΠΈ ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π΅Π³ΠΎ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎ. Π­Ρ‚ΠΎ ΠΏΠΎΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠ½ΡΡ‚ΡŒ, связана Π»ΠΈ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ° с контСкстом ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°.

πŸ’‘

Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ статичСскиС Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€Ρ‹ ΠΊΠΎΠ΄Π°, Ρ‚Π°ΠΊΠΈΠ΅ ΠΊΠ°ΠΊ Cppcheck ΠΈΠ»ΠΈ Clang-Tidy, Ρ‡Ρ‚ΠΎΠ±Ρ‹ автоматичСски Π½Π°Ρ…ΠΎΠ΄ΠΈΡ‚ΡŒ ΠΏΠΎΡ‚Π΅Π½Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹Π΅ ошибки с областями видимости.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ ΠΊΠΎΠ΄Π°: Π΄ΠΎ ΠΈ послС исправлСния

Π Π°Π·Π±Π΅Ρ€Ρ‘ΠΌ нСсколько Ρ€Π΅Π°Π»ΡŒΠ½Ρ‹Ρ… ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΎΠ² с ошибками ΠΈ ΠΈΡ… исправлСнными вСрсиями.

ΠžΡˆΠΈΠ±ΠΎΡ‡Π½Ρ‹ΠΉ ΠΊΠΎΠ΄ Ошибка Π˜ΡΠΏΡ€Π°Π²Π»Π΅Π½Π½Ρ‹ΠΉ ΠΊΠΎΠ΄
#include 

int main() {

for (int i = 0; i < 5; i++) {

std::cout << i;

}

std::cout << i; // β†’

return 0;

}

'i' was not declared in this scope
int i;

for (i = 0; i < 5; i++) {

std::cout << i;

}

std::cout << i;

#include 

int main() {

std::vector data;

data.push_back(1);

return 0;

}

'vector' is not a member of 'std'
#include 

#include // ← Π”ΠΎΠ±Π°Π²Π»Π΅Π½

int main() {

std::vector data;

data.push_back(1);

return 0;

}

namespace math {

int square(int x) { return x * x; }

}

int main() {

cout << square(5);

return 0;

}

'cout' and 'square' not declared
#include 

namespace math {

int square(int x) { return x * x; }

}

int main() {

std::cout << math::square(5);

return 0;

}

ΠŸΡ€ΠΎΡ„ΠΈΠ»Π°ΠΊΡ‚ΠΈΠΊΠ° ошибок: Π»ΡƒΡ‡ΡˆΠΈΠ΅ ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠΈ

Π§Ρ‚ΠΎΠ±Ρ‹ ΠΌΠΈΠ½ΠΈΠΌΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ риск ΡΡ‚ΠΎΠ»ΠΊΠ½ΡƒΡ‚ΡŒΡΡ с ошибкой Β«was not declared in this scopeΒ»**, слСдуйтС этим рСкомСндациям:

  • πŸ”Ή Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ согласованноС ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½ΠΈΠ΅. ΠŸΡ€ΠΈΠ΄Π΅Ρ€ΠΆΠΈΠ²Π°ΠΉΡ‚Π΅ΡΡŒ ΠΎΠ΄Π½ΠΎΠ³ΠΎ стиля (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, camelCase ΠΈΠ»ΠΈ snake_case), Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ·Π±Π΅Π³Π°Ρ‚ΡŒ ΠΎΠΏΠ΅Ρ‡Π°Ρ‚ΠΎΠΊ.
  • πŸ”Ή ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π°ΠΉΡ‚Π΅ Ρ…Π΅Π΄Π΅Ρ€Ρ‹ Π² ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎΠΌ порядкС. Π‘Π½Π°Ρ‡Π°Π»Π° стандартныС Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ, Π·Π°Ρ‚Π΅ΠΌ сторонниС, Π·Π°Ρ‚Π΅ΠΌ свои. Π­Ρ‚ΠΎ ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ‚ ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ ΠΊΠΎΠ½Ρ„Π»ΠΈΠΊΡ‚ΠΎΠ².
  • πŸ”Ή Π˜Π·Π±Π΅Π³Π°ΠΉΡ‚Π΅ using namespace Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½Ρ‹Ρ… Ρ„Π°ΠΉΠ»Π°Ρ…. Π­Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ привСсти ΠΊ ΠΊΠΎΠ½Ρ„Π»ΠΈΠΊΡ‚Π°ΠΌ ΠΈΠΌΡ‘Π½ Π² Π±ΠΎΠ»ΡŒΡˆΠΈΡ… ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°Ρ….
  • πŸ”Ή Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ соврСмСнныС стандарты C++. НапримСр, auto ΡƒΠΌΠ΅Π½ΡŒΡˆΠ°Π΅Ρ‚ Π²Π΅Ρ€ΠΎΡΡ‚Π½ΠΎΡΡ‚ΡŒ ошибок с Ρ‚ΠΈΠΏΠ°ΠΌΠΈ:
for (auto i = 0; i < 10; i++) { // Π’ΠΈΠΏ выводится автоматичСски

// ...

}

Π’Π°ΠΊΠΆΠ΅ ΠΏΠΎΠ»Π΅Π·Π½ΠΎ Π½Π°ΡΡ‚Ρ€Π°ΠΈΠ²Π°Ρ‚ΡŒ IDE Π½Π° подсвСтку Π½Π΅ΠΎΠΏΡ€Π΅Π΄Π΅Π»Ρ‘Π½Π½Ρ‹Ρ… ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ΠΎΠ². Π’ Visual Studio это дСлаСтся Ρ‡Π΅Ρ€Π΅Π· Tools β†’ Options β†’ Text Editor β†’ C/C++ β†’ Advanced β†’ IntelliSense.

πŸ’‘

ВсСгда ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΡƒΠΉΡ‚Π΅ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ (Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Π΅ Ρ„Π°ΠΉΠ»Ρ‹), Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π²Ρ‹ΡΠ²ΠΈΡ‚ΡŒ скрытыС ошибки связывания ΠΈΠ»ΠΈ объявлСний.

FAQ: ЧастыС вопросы ΠΏΠΎ ошибкС

ΠŸΠΎΡ‡Π΅ΠΌΡƒ компилятор Π½Π΅ Π²ΠΈΠ΄ΠΈΡ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ, хотя я ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΠ» Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ»?

Π’ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Π΅ ΠΏΡ€ΠΈΡ‡ΠΈΠ½Ρ‹:

  • πŸ”Ή Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ» Π½Π΅ содСрТит объявлСния Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ (ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅ Π΅Π³ΠΎ содСрТимоС).
  • πŸ”Ή Ѐункция объявлСна Π²Π½ΡƒΡ‚Ρ€ΠΈ пространства ΠΈΠΌΡ‘Π½, Π½ΠΎ Π²Ρ‹ Π½Π΅ ΡƒΠΊΠ°Π·Π°Π»ΠΈ Π΅Π³ΠΎ ΠΏΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅.
  • πŸ”Ή Ошибка Π² сигнатурС (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π·Π°Π±Ρ‹Π»ΠΈ const ΠΈΠ»ΠΈ ссылку &).
  • πŸ”Ή Π€Π°ΠΉΠ» Π½Π΅ компилируСтся ΠΈΠ·-Π·Π° условных Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΈΠ² (#ifdef).

РСшСниС: ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅ прСпроцСссированный Π²Ρ‹Π²ΠΎΠ΄ (g++ -E) ΠΈΠ»ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ #include с ΠΏΠΎΠ»Π½Ρ‹ΠΌ ΠΏΡƒΡ‚Ρ‘ΠΌ для ΠΎΡ‚Π»Π°Π΄ΠΊΠΈ.

МоТно Π»ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ ΠΈΠ· ΠΎΠ΄Π½ΠΎΠ³ΠΎ .cpp Ρ„Π°ΠΉΠ»Π° Π² Π΄Ρ€ΡƒΠ³ΠΎΠΌ?

НСт, Ссли пСрСмСнная Π½Π΅ объявлСна ΠΊΠ°ΠΊ extern Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½ΠΎΠΌ Ρ„Π°ΠΉΠ»Π΅. ΠŸΡ€ΠΈΠΌΠ΅Ρ€:

// config.hpp

extern int globalConfig; // ОбъявлСниС

// config.cpp

int globalConfig = 42; // ΠžΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅

// main.cpp

#include "config.hpp"

int main() {

std::cout << globalConfig; // Π Π°Π±ΠΎΡ‚Π°Π΅Ρ‚

return 0;

}

Для констант Π»ΡƒΡ‡ΡˆΠ΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ inline const (начиная с C++17):

inline const int MaxSize = 100;
ΠŸΠΎΡ‡Π΅ΠΌΡƒ ошибка появляСтся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΡ€ΠΈ связывании (ld), Π° Π½Π΅ ΠΏΡ€ΠΈ компиляции?

Π­Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ объявлСн (компилятор Π΅Π³ΠΎ Β«Π²ΠΈΠ΄ΠΈΡ‚Β»), Π½ΠΎ Π½Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Ρ‘Π½ (Π½Π΅Ρ‚ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ). Π’ΠΈΠΏΠΈΡ‡Π½Ρ‹Π΅ случаи:

  • πŸ”Ή Π—Π°Π±Ρ‹Π»ΠΈ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ, ΠΎΠ±ΡŠΡΠ²Π»Π΅Π½Π½ΡƒΡŽ Π² Ρ…Π΅Π΄Π΅Ρ€Π΅.
  • πŸ”Ή ΠžΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ находится Π² .cpp Ρ„Π°ΠΉΠ»Π΅, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π½Π΅ скомпилирован ΠΈΠ»ΠΈ Π½Π΅ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ Π² ΠΏΡ€ΠΎΠ΅ΠΊΡ‚.
  • πŸ”Ή Для шаблонов: ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±Ρ‹Ρ‚ΡŒ Π² Ρ…Π΅Π΄Π΅Ρ€Π΅ (ΠΈΠ»ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΡΠ²Π½ΡƒΡŽ ΠΈΠ½ΡΡ‚Π°Π½Ρ†ΠΈΠ°Ρ†ΠΈΡŽ).

РСшСниС: ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅, Ρ‡Ρ‚ΠΎ всС .cpp Ρ„Π°ΠΉΠ»Ρ‹ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½Ρ‹ Π² CMakeLists.txt ΠΈΠ»ΠΈ Makefile.

Как Π±Ρ‹Ρ‚ΡŒ, Ссли ошибка Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ‚ Π² стороннСй Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ΅?

Π’ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Π΅ дСйствия:

  1. ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅, Ρ‡Ρ‚ΠΎ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ установлСна ΠΈ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½Π° (-I для инклюдов, -L ΠΈ -l для Π»ΠΈΠ½ΠΊΠΎΠ²ΠΊΠΈ).
  2. Π£Π±Π΅Π΄ΠΈΡ‚Π΅ΡΡŒ, Ρ‡Ρ‚ΠΎ вСрсии Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ ΠΈ Π΅Ρ‘ Ρ…Π΅Π΄Π΅Ρ€ΠΎΠ² ΡΠΎΠ²ΠΏΠ°Π΄Π°ΡŽΡ‚.
  3. ΠŸΠΎΡΠΌΠΎΡ‚Ρ€ΠΈΡ‚Π΅ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡŽ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ β€” Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, трСбуСтся ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ макрос (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, -DUSE_LIBRARY).
  4. Если Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° шаблонная (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Eigen), ΡƒΠ±Π΅Π΄ΠΈΡ‚Π΅ΡΡŒ, Ρ‡Ρ‚ΠΎ всС Ρ…Π΅Π΄Π΅Ρ€Ρ‹ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½Ρ‹ Π΄ΠΎ ΠΈΡ… использования.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ для Boost:

g++ -I/path/to/boost main.cpp -o program
ΠœΠΎΠΆΠ΅Ρ‚ Π»ΠΈ ошибка Π±Ρ‹Ρ‚ΡŒ связана с вСрсиСй стандарта C++?

Π”Π°! НСкоторыС ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Ρ‹ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, std::optional) Ρ‚Ρ€Π΅Π±ΡƒΡŽΡ‚ C++17 ΠΈΠ»ΠΈ Π½ΠΎΠ²Π΅Π΅. Если Π²Ρ‹ Π½Π΅ ΡƒΠΊΠ°Π·Π°Π»ΠΈ стандарт явно, компилятор ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ C++98/03 ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ.

РСшСниС: Π΄ΠΎΠ±Π°Π²ΡŒΡ‚Π΅ Ρ„Π»Π°Π³ стандарта:

g++ -std=c++17 main.cpp -o program

Для CMake:

set(CMAKE_CXX_STANDARD 17)