Почему код C ++ иногда компилируется, а иногда выдает ошибку компиляции в зависимости от предыдущих компиляций? - PullRequest
0 голосов
/ 17 апреля 2019

Я изучаю конструкторы в C ++, но компилятор MSVS ведет себя странно, и я не понимаю, почему. Успех компилятора, похоже, зависит от недавних попыток компиляции. Я ожидаю, что если мой код успешно компилируется один раз, он всегда должен успешно компилироваться, а если он дает ошибку, он всегда должен давать ошибку. С моим кодом здесь это не так. Я использую отладчик в бесплатной среде MSVS 2019 на Windows 10.

У меня есть 3 файла, которые формируют мой проект, и 3 разные версии проекта, которые я назову A, B и C.

Версия A - это код, представленный на первых трех экранах ниже. Я думаю, что версия А должна скомпилироваться и работать так, как я ожидаю. Любые фактические ошибки в версии A, вероятно, являются вторичными по отношению к этому вопросу. Код должен определить класс, создать экземпляр класса (запустить конструктор), вызвать метод класса и, наконец, вызвать деструктор. для этого объекта, когда программа завершается.

Следующий код находится в Cat.h.

#pragma once
#include <iostream>

class Cat {

private:
    bool happy;

public:
    Cat();
    ~Cat();
    void meow();
};

Следующее находится в файле Cat.cpp.

#include <iostream>
#include "Cat.h"

Cat::Cat() {
    std::cout << "Creating Cat" << std::endl;
    happy = false;
};

Cat::~Cat() {
    std::cout << "Deleting Cat..." << std::endl;
};

void Cat::meow() {
    if (happy) {
        std::cout << "Meow" << std::endl;
    }
    else
    {
        std::cout << "SSSSSsssss" << std::endl;
    }
    return;
};

Вот мой основной файл.

#include "Cat.h"

int main() {
    Cat cat;
    cat.meow();
}

Версия B идентична версии A , за исключением одного изменения, которое объявляется в конструкторе для Cat, что делает счастливой локальную переменную конструктора.

Cat::Cat() {
    std::cout << "Creating Cat" << std::endl;
    bool happy = false;
}

Версия C идентична версии A , за исключением явной ошибки, заключающейся в том, что точка с запятой удаляется после объявления класса в Cat.h.

    Cat();
    ~Cat();
    void meow();
}

Теперь о странном поведении.

Если я впервые попытаюсь скомпилировать версию A , я получу следующие ошибки:

1>Debug\Cat.obj : warning LNK4042: object specified more than once; extras ignored
1>Source.obj : error LNK2019: unresolved external symbol "public: __thiscall Cat::Cat(void)" (??0Cat@@QAE@XZ) referenced in function _main
1>Source.obj : error LNK2019: unresolved external symbol "public: __thiscall Cat::~Cat(void)" (??1Cat@@QAE@XZ) referenced in function _main
1>Source.obj : error LNK2019: unresolved external symbol "public: void __thiscall Cat::meow(void)" (?meow@Cat@@QAEXXZ) referenced in function _main

Если я сейчас изменю версию A на версию B и скомпилирую, я не получу ошибок, но я не инициализируюсь счастливым в конструкторе cat. Если я затем изменю версию B на версию A , код компилируется и запускается так, как я ожидал.

Теперь версия A компилируется и запускается, даже несмотря на то, что это тот же код, который выдавал мне ошибку раньше.

Если я сейчас изменю версию A на версию C и скомпилирую, я получу очевидную ошибку:

 1>Cat.cpp
 error C2533: 'Cat::{ctor}': constructors not allowed a return type
 1>Cat.h 
 fatal error C1004: unexpected end-of-file found

Если я теперь изменю версию C на версию A и скомпилирую, я получу ту же ошибку, которая произошла после первоначальной компиляции версии A . Возвращение к версии B и обратно исправляет эту проблему.

...