【问题标题】:How to fix variable declaration and global constructor warnings?如何修复变量声明和全局构造函数警告?
【发布时间】:2018-02-11 08:33:05
【问题描述】:

我正在阅读 C++ 如何编程 并尝试使用我目前所学的知识(哈!)并编写了这个程序。 (这是我自己的事情,不是书中的练习。)输出是我想要的,但我无法修复警告。

我在 Game.h 中对 random 的使用是基于我在书中看到的。

如果我将导致警告的行放在main() 中,错误就会消失,但编译器会抛出一个致命错误,因为它不再可以访问变量engine。我明白了。

我感到很沮丧,因为我以为我在学习 C++,但 C++11 的东西似乎很快就让我忘记了。

游戏.h

#include <iostream>
#include <array>
#include <ctime>
#include <random>

std::default_random_engine engine( static_cast< unsigned int >( time(0) ) );
std::uniform_int_distribution< int > randomInt( 0, 23 );
void initPieces( std::array< int, 24 >& );
void showPieces( std::array< int, 24 > );

main.cpp

#include "Game.h"

int main() {
  std::array< int, 24 > piecesPlayer1 = {};
  std::array< int, 24 > piecesPlayer2 = {};
  initPieces ( piecesPlayer1 );
  initPieces ( piecesPlayer2 );
}

void initPieces( std::array< int, 24 >& myPieces) {
  for ( unsigned int i = 0; i < 24; i += 3 ) {
    myPieces[ i ] = 1;
    myPieces[ i + 1 ] = 2;
    myPieces[ i + 2 ] = 3;
  }
  for ( unsigned int i = 0; i < 24; i++ ) {
    int s = randomInt( engine );
    std::swap ( myPieces[ i ], myPieces[ static_cast<unsigned int>( s ) ] );
  }
  showPieces ( myPieces );
}

void showPieces( std::array< int, 24 > myPieces) {
  for ( unsigned int i = 0; i < 24; i++ ) {
    std::cout << myPieces[ i ] << " ";
  }
  std::cout << std::endl;
}

编辑:我忘了包括警告。

rm -fr build/*
clang++ -std=c++11 -stdlib=libc++ -Weverything -Wno-c++98-compat src/main.cpp -o build/main -Isrc/
In file included from src/main.cpp:1:
src/Game.h:7:28: warning: no previous extern declaration for non-static variable 'engine' [-Wmissing-variable-declarations]
std::default_random_engine engine( static_cast< unsigned int >( time(0) ) );
                           ^
src/Game.h:7:28: warning: declaration requires a global constructor [-Wglobal-constructors]
std::default_random_engine engine( static_cast< unsigned int >( time(0) ) );
                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/Game.h:8:38: warning: no previous extern declaration for non-static variable 'randomInt' [-Wmissing-variable-declarations]
std::uniform_int_distribution< int > randomInt( 0, 23 );
                                     ^
src/Game.h:8:38: warning: declaration requires a global constructor [-Wglobal-constructors]
std::uniform_int_distribution< int > randomInt( 0, 23 );
                                     ^~~~~~~~~~~~~~~~~~
4 warnings generated.
./build/main
2 3 2 3 3 2 2 2 2 1 1 3 2 1 3 1 1 1 3 3 3 1 1 2
2 3 3 1 2 3 3 2 1 2 1 2 1 1 3 2 3 1 3 2 3 1 2 1

【问题讨论】:

  • 警告是什么?
  • @NathanOliver 是的。我忘了包括他们。我已经编辑了它们。
  • 我的?因为您在头文件中定义了变量。头文件几乎不应该定义变量,只声明它们。想想如果您尝试在多个源文件中包含相同的头文件会发生什么。然后该变量将在多个不允许的地方定义。对于您这样一个简单的程序,您实际上并不需要头文件。只有在多个源文件中需要变量或函数声明或结构时,它才有用。
  • 除非你真的、真的知道你在做什么,否则不要在 clang 中使用-Weverything
  • 使用-Wall 而不是-Weverything。除非您像我一样是强迫症,否则请使用 -Weverything 并准备好进行大量代码润色......因为它很有趣!

标签: c++ c++11


【解决方案1】:

使用C++17,你可以用inline装饰game.h:

#pragma once

#include <iostream>
#include <array>
#include <ctime>
#include <random>

inline std::default_random_engine engine(static_cast< unsigned int >(time(0)));
inline std::uniform_int_distribution< int > randomInt(0, 23);
void initPieces(std::array< int, 24 >&);
void showPieces(std::array< int, 24 >);

对于旧的 C++,将标头更改为:

#pragma once

#include <iostream>
#include <array>
#include <ctime>
#include <random>

extern std::default_random_engine engine;
extern std::uniform_int_distribution< int > randomInt;
void initPieces(std::array< int, 24 >&);
void showPieces(std::array< int, 24 >);

将定义放入 main.cpp 或其他一些编译单元,例如游戏.cpp.

std::default_random_engine engine(static_cast< unsigned int >(time(0)));
std::uniform_int_distribution< int > randomInt(0, 23);

【讨论】:

  • 我很欣赏这个答案。我在使用 C+11 时没有完全理解为什么,因为我正在学习的书使用它。我对 C++17 一无所知。不过,我确实将定义从头文件中移出。
  • 答案也涵盖了 C++11。进一步阅读。
  • 在“旧版本”中,标头对象声明必须有extern——否则它们仍然是定义,只是没有给出构造函数参数
猜你喜欢
  • 2017-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-20
  • 1970-01-01
  • 2014-01-17
  • 2014-10-30
相关资源
最近更新 更多