12
回答
G++编译器的一个bug
注册华为云得mate10,2.9折抢先购!>>>   

我是一个ubuntu11.10的用户,g++的版本是4.6.1.加上-std=c++0x可选项时会出现奇怪的报错。由于本人比较懒,试图把代码缩小的时候那些奇怪的bug有神秘的消失了,所以,把所有有关的源码贴上来。其中header,src,bin,obj是同一层次的文件夹。

header/algo/inter.h:

/*********************************************************************************
 * class Point, Pnel, Old_panel, New_Panel, Algo_main
 *
 * In Panel(const int num), num means the old or new style panel,15 new and 19 old
 * In Panel(const string str), str means filepath  saved the previous panel
 * Panel.getforbids() get forbid point from thinker::Panel_pos 
 * New_panel.stack and Old_panel.stack is a two heads stack
 *
 * Algo_main.regret_regret will be involked when the player regret his or her regret
 *********************************************************************************/

#define INTER_H

#include<string>
#include<vector>
using namespace std ;

namespace inter{

    enum Flag{EMPTY, BLACK, WHITE} ;

    class Point{
	public:
	    Point(const int a, const int b) : x(a), y(b) {} ;
	    int x ;
	    int y ;
    } ;

    class Panel{
	public:
	    Panel() ;
	    Panel(const int num) ;
	    Panel(const string& str) ;
	    Panel(const Panel& panel) ;
	    ~Panel() ;
	    virtual void put(const Point& point, const Flag& lable) ;
	    virtual void save() const ;
	    virtual void save(const string str) const ;
	    virtual void read(const Point& point, const Flag& lable) ;
	    virtual void read(const string& str) ;   
	    virtual void repeal() ;
	    virtual void reput() ;

	    virtual void getforbids() ;

	private:

	    static int lable ;  // to make sure only one copy of Panel exists

	    string str ; 

	    static const int num_of_forbids = 10 ;

	    vector<Point> forbids ;
    } ;

    class Old_panel : virtual public Panel {
	public:
	    Old_panel() ;

	    static const int num = 19;  

	private:
	    Flag panel[num][num] ;
	    Flag stack[num * num] ;
    } ;

    class New_panel : virtual public Panel {
	public:
	    New_panel() ;

	    static const int num = 15;  

	private:
	    Flag panel[num][num] ;
	    Flag stack[num * num] ;
    } ;

    class Algo_main{
	public:
	    Algo_main() ;
	    Algo_main(const string conf, const string file = "") ;
	    virtual void setlevel(const int level) ;
	    virtual void addreg(const Flag flag, const int num) ; 
	    virtual void delreg(const Flag flag, const int num) ;
	    virtual Point getreply(const Point& point) ;
	    virtual void regret() ;
	    virtual void regret_regret() ;
	    virtual void save() ;
	    virtual void changepanel(const int num) ;
    } ;
}

header/algo/thinker.h:

/**********************************************************************
 * In this head file, lables are expressed by int. For example,in 
 * 	Regulation 344,the lables is 3, 4, 4
 *
 * global array reg store all the regulations to simplify the programm
 *
 * class Regulation, Regulations, Position, Panel_pos, Onestep Sorter
 *       Think
 * 
 * Regulation has a constructor with multiule argus
 *
 * Regulations.addreg's argu means the numth regulation, only turn on
 * 	or turn off the numth switch,and so is to the delreg.
 *
 * Position flags one point on the panel, with score and lables
 *
 * Onestep is one step in the progress of think, side effects appeals 
 * 	on the the Panel_pos, and are ereased by the function undo.
 *
 * Sorter manage the candidates of the point on the Panel_pos.
 *
 * Think thinks how to reply to the reaction of human,and manage Regulations.
 *********************************************************************/

#define DEBUG 


#ifdef DEBUG
#include<iostream>
using namespace std ;
#endif 

#define THINKER_H

#include"inter.h" 
namespace thinker{

    using inter::Flag ;
    using inter::Panel ;
    using inter::New_panel ;
    using inter::Old_panel ;
    using inter::Point ;


    class Regulation{
	public:
	    Regulation(int argc, ...) ;

	    static const int num_of_lables = 5 ;

	    int reg[num_of_lables] ;

#ifdef DEBUG
	    void dis() const ;
#endif 

    } ;


    class Regulations{
	public:
	    Regulations() ;
	    virtual void addreg(const int numth) ;
	    virtual void delreg(const int numth) ;

	    static const int num_of_regs = 10 ;
	    static const int num_of_all_lables = 10 ;
	    
	    int lables[num_of_all_lables] ;
	    int regs[num_of_regs];

#ifdef DEBUG
	    void dis() const ;
#endif

    } ;

    class Position{
	public:
	    int lables[Regulation::num_of_lables] ;
	    int score ;
    } ;

    class Panel_pos : virtual public Panel{
	public:
	    static Regulations white_reg ;
	    static Regulations black_reg ;

    } ;
    
    class New_panel_pos : virtual public Panel_pos, virtual public New_panel {
	public:
	    Position pos[New_panel::num][New_panel::num] ;
    } ;

    class Old_panel_pos : virtual public Panel_pos, virtual public Old_panel {
	public:
	    Position pos[Old_panel::num][Old_panel::num] ;
    } ;

    class Onestep{
	public:
	    Onestep(const Point& point, const Flag flag) ;
	    virtual void undo() ;
	    virtual void check() ;

	    static const int num_of_changes = 20 ;
	    static const int num_of_adds = 10 ;
	    static const int num_of_dels = 10 ;
	    
	private:

	    static Flag flag ;

	    Point point ;
	    vector<Position> changes ;
	    vector<Position> adds ;
	    vector<Position> dels ;
    } ;

    class Sorter{
	public:
	    virtual int addelm(const Point& point) ;
	    virtual int delelm(const Point& point) ;
	    virtual int chgelm(const Point& point, const int score) const ;
	    virtual int chgelm_add(const Point& point, const int adder) const ;
	    virtual int chgelm_min(const Point& point, const int minner) const ;
    } ;

    class Think{
	public:
	    virtual Point thinking(Point point, int level, const int nums = 1) ;
	    virtual void addreg(const Flag flag, const int numth) ;
	    virtual void delreg(const Flag flag, const int numth) ;
    } ;
} ;

src/reg.cpp:

#ifndef THINKER_H
#include"thinker.h"
#endif

#include<cstdarg>
using namespace std ;

namespace thinker{
    Regulation::Regulation(int argc, ...){
	va_list ap ;
	va_start(ap, argc) ;
	int i = 0 ;
	for(i = 0; i < argc && i < num_of_lables; i++){
	    reg[i] = va_arg(ap, int) ;
	}
	va_end(ap) ;
	if(i < num_of_lables){
	    reg[i] = 0 ;
	}else if(num_of_lables == i){
	    reg[num_of_lables - 1] = 0 ;
	}
    }

#ifdef DEBUG
    void Regulation::dis() const {
	for(int i = 0; i < 5; i++){
	    cout << reg[i] << endl ;
	}
    }
#endif 

} ;

#ifdef DEBUG
/*
int main(int argc, char* argv[]){
    using namespace thinker ;
    //Regulation reg() ;          error
    //Regulation reg(-1,3,3,4) ;  0,num, num...
    //Regulation reg(3,3,3,4) ;   3,3,4.num...
    //Regulation reg(3,-3,3,4) ;    -3,3,4,num...
    reg.dis() ;
    return 0 ;
}
*/
#endif

src/regs.cpp:

#ifndef THINKER_H
#include"thinker.h"
#endif
namespace thinker{

    const Regulation reg_all[2] = {Regulation(2,3,3), Regulation(2,3,4)} ;

    Regulations::Regulations(){
	for(int i = 0; i < num_of_all_lables; i++){
	    lables[i] = 0 ;
	}
	for(int i = 0; i < num_of_regs; i++){
	    regs[i] = 0 ;
	}
    } ;

    void Regulations::addreg(const int numth){
	if(1 == regs[numth]){

	}else{
	    regs[numth] = 1 ;
	    for(int i = 0; i < Regulation::num_of_lables && reg_all[numth].reg[i] != 0; i++){
		lables[reg_all[numth].reg[i]]++ ;
	    }
	}
    }

    void Regulations::delreg(const int numth){
	if(0 == regs[numth]){

	}else{
	    regs[numth] = 0 ;
	    for(int i = 0; i < Regulation::num_of_lables && reg_all[numth].reg[i] != 0; i++){
		lables[reg_all[numth].reg[i]]-- ;
	    }
	}
    }

#ifdef DEBUG
    void Regulations::dis() const {
	for(int i = 0; i < num_of_all_lables; i++){
	    cout << lables[i] << endl ;
	}
	cout << endl ;
	for( int i = 0; i != num_of_regs; i++){
	    if(regs[i] != 0){
		reg_all[i].dis() ;
	    } 
	   cout << endl ;
	   cout << endl ;
	}
   }
#endif 
}

#ifdef DEBUG
int main(int argc, char* argv[]){
    using namespace thinker ;
    Regulations regs ;
    regs.addreg(0) ;
    regs.addreg(0) ;
    regs.addreg(0) ;
    regs.addreg(1) ;
    regs.delreg(0) ;
    regs.delreg(1) ;
    regs.delreg(1) ;
    regs.dis() ;
    return 0 ;
}
#endif

makefile:

.build:build
build:src/regs.cpp obj/reg.o
	g++ -Iheader/algo obj/reg.o src/regs.cpp -o bin/regs -Wall
obj/reg.o:header/algo/thinker.h src/reg.cpp
	g++ -c -Iheader/algo src/reg.cpp -o obj/reg.o -Wall

这是个人工智能的五子棋算法,正在实现剩下的的class和函数。

GCC
举报
jackandrose
发帖于6年前 12回/6K+阅
共有12个答案 最后回答: 6年前

引用来自“千羽鸣”的答案

光看到贴上来一堆充满神奇数的代码,报错信息在哪儿呢?
g++ -std=c++0x -Iheader/algo obj/reg.o src/regs.cpp -o bin/regs -Wall
src/regs.cpp: In member function ‘virtual void thinker::Regulations::addreg(int)’:
src/regs.cpp:18:20: error: ISO C++ forbids comparison between pointer and integer [-fpermissive]
src/regs.cpp:21:20: error: invalid conversion from ‘int’ to ‘thinker::Regulation*’ [-fpermissive]
src/regs.cpp: At global scope:
src/regs.cpp:40:10: error: prototype for ‘void thinker::Regulations::dis() const’ does not match any in class ‘thinker::Regulations’
header/algo/thinker.h:77:11: error: candidate is: void thinker::Regulations::dis()
make: *** [build] Error 1
这是报错信息。其实你完全可以自己试一下。
--- 共有 2 条评论 ---
jackandrose但是把-std=c++0x去掉,就没有任何问题了 6年前 回复
吃土的汉子看到前面几条error就知道我用不着试了,代码问题。 你真要提bug到G++邮件组,我就不讨论您这高级代码了 6年前 回复

引用来自“solookin”的答案

代码问题。
把-std=c++0x去点就没有任何问题了
--- 共有 1 条评论 ---
solookin不过我不太清楚g++ 4.6.1 支不支持c++0x 6年前 回复

引用来自“xunxun”的答案

我看到出错信息里有-fpermissive就不用看了
把-std=c++0x去掉就没有任何问题了

引用来自“jackandrose”的答案

引用来自“xunxun”的答案

我看到出错信息里有-fpermissive就不用看了
把-std=c++0x去掉就没有任何问题了

我说的就是这个意思

建议你看看详细的标准

加入-std表示严格符合某一标准,否则就会有-fpermissive之类的提示

gcc4.7发布之后也影响到一群开源软件,这也是更贴近标准的严格提示,并不是编译器的bug。

你可以同时加入-fpermissive试试

引用来自“xunxun”的答案

引用来自“jackandrose”的答案

引用来自“xunxun”的答案

我看到出错信息里有-fpermissive就不用看了
把-std=c++0x去掉就没有任何问题了

我说的就是这个意思

建议你看看详细的标准

加入-std表示严格符合某一标准,否则就会有-fpermissive之类的提示

gcc4.7发布之后也影响到一群开源软件,这也是更贴近标准的严格提示,并不是编译器的bug。

你可以同时加入-fpermissive试试

你要是试了就会知道,在header/algo/thiinker.h中生命的一个整形数组regs,在src/regs.cpp中让regs[1]和1比较,就会报错说标准不允许整形和指针类型之间的比较,进行赋值就说把整形转化成指针类型是不合法的。还有更滑稽的,函数所在的行数都报错了。并且,你试试就知道了。
顶部