Home > Enterprise >  Unexpected error resloved by using <iostream> header
Unexpected error resloved by using <iostream> header

Time:10-15

Sorry if this code is too long. When I tried to reproduce this problem, it show the expect result.

So I was trying to make a BigInteger header:

BIGINT.h

#ifndef BIGINT_H
#define BIGINT_H

//#include <iostream> 

#include <string>
#include <vector>
#include <cctype>
#include <cassert>
#include <cstddef>

extern short DEFAULT_BASE;

class BigInt
{
private:
    bool m_sign; // (0/false) mean negative, (1/true) mean positive
    std::string m_number;
    unsigned char m_base;

public:
    // constructor
    BigInt(std::string number = "0", unsigned char base = DEFAULT_BASE);
    BigInt(unsigned char base, std::string number = "0");
    BigInt(const BigInt &copy);

    //destructor
    ~BigInt();

    // get member value
    std::string number() const;
    unsigned char base() const;
    bool is_number_positive() const;

    // I/O overload
    friend std::ostream& operator<< (std::ostream& out, const BigInt& bigInt);
    friend std::istream& operator>> (std::istream& in, BigInt& bigInt);


};


#endif // BIGINT_H

BIGINT.cpp

#include "BIGINT.h"

short DEFAULT_BASE = 10;

// constructor
BigInt::BigInt(std::string number, unsigned char base)
{
{
    {
        int i{0};
        int numberOfSubtraction{0};
        while (number[i] == '-' || number[i] == ' ')
        {
            numberOfSubtraction  = number[i] == '-';
              i;
        }

        m_sign = numberOfSubtraction % 2 == 0;

        number = number.substr(i);
    }
    // std::cerr << base << ' ';
    assert(base >= 2 && base <= 36);
    for(char &i : number)
    {
        if(isdigit(i)) assert(i - '0' < base);
        else if(isalpha(i)) assert(i - 'A'   10 < base);
        m_number  = toupper(i);
    }
    m_base = base;


}

BigInt::BigInt(unsigned char base, std::string number)
{
    {
        int i{0};
        int numberOfSubtraction{0};
        while (number[i] == '-' || number[i] == ' ')
        {
            numberOfSubtraction  = number[i] == '-';
              i;
        }

        m_sign = numberOfSubtraction % 2 == 0;

        number = number.substr(i);
    }
    // std::cerr << base << ' ';
    assert(base >= 2 && base <= 36);
    for(char &i : number)
    {
        if(isdigit(i)) assert(i - '0' < base);
        else if(isalpha(i)) assert(i - 'A'   10 < base);
        m_number  = toupper(i);
    }
    m_base = base;

}

BigInt::BigInt(const BigInt &copy)
{
    m_number = copy.m_number;
    m_base = copy.m_base;
}

// destructor
BigInt::~BigInt() = default;

// get member value
std::string BigInt::number() const {return m_number;}
unsigned char BigInt::base() const {return m_base;}
bool BigInt::is_number_positive() const {return m_sign;}

// I/O overload
std::ostream& operator<< (std::ostream& out, const BigInt& bigInt)
{
    if(!bigInt.m_sign) out << '-';
    out << bigInt.m_number;

    return out;
}

std::istream& operator>> (std::istream& in, BigInt& bigInt)
{
    std::string number;
    in >> number;
    {
        int i{0};
        int numberOfSubtraction{0};
        while (number[i] == '-' || number[i] == ' ')
        {
            numberOfSubtraction  = number[i] == '-';
              i;
        }

        bigInt.m_sign = numberOfSubtraction % 2 == 0;

        number = number.substr(i);
    }
    for(char &i : number)
    {
        if(isdigit(i)) assert(i - '0' < DEFAULT_BASE);
        else if(isalpha(i)) assert(i - 'A'   10 < DEFAULT_BASE);
        bigInt.m_number  = toupper(i);
    }
    return in;
}

main.cpp

#include "BIGINT.h"

#include <iostream>
#include <string>

int main()
{
    BigInt bigInt{" - --- - -- 1", 10};
    std::cout << bigInt ;
}

So I run this, and it assert: Assertion failed: base >= 2 && base <= 36, file D:\phamngocphuc\C project\BigInt\BIGINT.cpp, line 49, which is unexpected because:

Firstly, it should call this constructor BigInt(std::string number = "0", unsigned char base = DEFAULT_BASE);

and not this BigInt(unsigned char base, std::string number = "0");

And my base actually should be good: (10 >= 2 && 10 <= 36) is true

Second, when I #include <iostream> in BIGINT.h to debug, and run it, it actually show -1 which is expected result.

So why is this happening?

CodePudding user response:

When you mark the offending constructor as deleted Demo.

Compiler spots where it is used, (and it is not where you think):

Issue is there:

std::ostream& operator<< (std::ostream& out, const BigInt& bigInt)
{
    if(!bigInt.m_sign) out << '-';
    out << bigInt.m_number;

    return out;
}

Without the include <iostream> (it seems you have some forward declaration from other std include to be able to use those types), out << '-'; just found as candidate std::ostream& operator<< (std::ostream& out, const BigInt& bigInt) (recursive call would also be problematic though).

So construct a BigInt from '-' (BigInt(unsigned char base, std::string number = "0");).

And then your error.

  • Related