Сообщение Загадка сборки проекта - на мин. примере от 10.07.2023 6:05
Изменено 10.07.2023 6:07 Shmj
Стадии сборки проекта - почему это важно (на примере)
В продолжение темы
В .Net я о стадиях сборки даже не думал. Знал что есть сборка и JIT-компиляция (вот там важно — иногда эта JIT-компиляция занимала 10 секунд, что удавалось решить Ngen-ом, причем важно было не перепутать битность платформы). А есть ли там какие стадии сборки — особо не думал об этом.
C C++, как оказалось, это критически важно и без этого даже не поймешь почему не работает прога. Думал хватит понимания что есть 3 стадии:
1. Препроцессор — раскрывает #include, #define, #if и пр.
2. Сам компилятор для каждого файла создает o-файл.
3. Линкер собирает все в единую библиотеку или exe-файл.
Оказалось что этого не достаточно, что видно из примера. Сейчас привожу максимально упрощенный пример, он из 3 файлов:
Файл demo.hpp
Файл demo.cpp
Файл с функцией входа:
Вопрос: почему если раскомментировать контруктор по умолчанию //BaseClass() {} — оно перестает компилироваться? Оказывается без понимания стадий сборки не поймешь этого. Тут чел. приводил стадии трансляции, возможно с этим тоже связано.
Честно сказать, даже доведя до мин. примера (общими силами), я не до конца понимаю почему возникает ошибка компиляции при явном консрукторе. Примерно так — если сборщик видит явный конструктор, то он уже не ищет реализацию класса DerivedClass а просто сразу отрабатывает assert. А вот если конструктор не указать явно, то почему assert не отрабатывает?
Вот положа руку на сердце — вы понимаете логику сбоки в этом случае?
Автор: Shmj
Дата: 05.07.23
, дабы довести до логического завершения. Всем спасибо за старания.Дата: 05.07.23
В .Net я о стадиях сборки даже не думал. Знал что есть сборка и JIT-компиляция (вот там важно — иногда эта JIT-компиляция занимала 10 секунд, что удавалось решить Ngen-ом, причем важно было не перепутать битность платформы). А есть ли там какие стадии сборки — особо не думал об этом.
C C++, как оказалось, это критически важно и без этого даже не поймешь почему не работает прога. Думал хватит понимания что есть 3 стадии:
1. Препроцессор — раскрывает #include, #define, #if и пр.
2. Сам компилятор для каждого файла создает o-файл.
3. Линкер собирает все в единую библиотеку или exe-файл.
Оказалось что этого не достаточно, что видно из примера. Сейчас привожу максимально упрощенный пример, он из 3 файлов:
Файл demo.hpp
#pragma once
template <typename T>
class Checker
{
public:
Checker()
{
static_assert(sizeof(T), "Incomplete type");
}
};
class DerivedClass;
class BaseClass
{
public:
//BaseClass() {}
static void fun1();
private:
Checker<DerivedClass> m;
};Файл demo.cpp
#include "demo.hpp"
class DerivedClass
{
};
//BaseClass::BaseClass()
//{
//}
void BaseClass::fun1()
{
}Файл с функцией входа:
#include "demo.hpp"
int main()
{
BaseClass::fun1();
}Вопрос: почему если раскомментировать контруктор по умолчанию //BaseClass() {} — оно перестает компилироваться? Оказывается без понимания стадий сборки не поймешь этого. Тут чел. приводил стадии трансляции, возможно с этим тоже связано.
Честно сказать, даже доведя до мин. примера (общими силами), я не до конца понимаю почему возникает ошибка компиляции при явном консрукторе. Примерно так — если сборщик видит явный конструктор, то он уже не ищет реализацию класса DerivedClass а просто сразу отрабатывает assert. А вот если конструктор не указать явно, то почему assert не отрабатывает?
Вот положа руку на сердце — вы понимаете логику сбоки в этом случае?
Стадии сборки проекта - почему это важно (на примере)
В продолжение темы
В .Net я о стадиях сборки даже не думал. Знал что есть сборка и JIT-компиляция (вот там важно — иногда эта JIT-компиляция занимала 10 секунд, что удавалось решить Ngen-ом, причем важно было не перепутать битность платформы). А есть ли там какие стадии сборки — особо не думал об этом.
C C++, как оказалось, это критически важно и без этого даже не поймешь почему не работает прога. Думал хватит понимания что есть 3 стадии:
1. Препроцессор — раскрывает #include, #define, #if и пр.
2. Сам компилятор для каждого файла создает o-файл.
3. Линкер собирает все в единую библиотеку или exe-файл.
Оказалось что этого не достаточно, что видно из примера. Сейчас привожу максимально упрощенный пример, он из 3 файлов:
Файл demo.hpp
Файл demo.cpp
Файл с функцией входа:
Вопрос: почему если раскомментировать контруктор по умолчанию //BaseClass() {} — оно перестает компилироваться? Оказывается без понимания стадий сборки не поймешь этого. Тут чел. приводил стадии трансляции, возможно с этим тоже связано.
Честно сказать, даже доведя до мин. примера (общими силами), я не до конца понимаю почему возникает ошибка компиляции при явном консрукторе. Примерно так — если сборщик видит явный конструктор, то он уже не ищет реализацию класса DerivedClass а просто сразу отрабатывает assert. А вот если конструктор не указать явно, то почему assert не отрабатывает?
Вот положа руку на сердце — вы понимаете логику сбоки в этом случае?
Автор: Shmj
Дата: 05.07.23
, дабы довести до логического завершения. Всем спасибо за старания.Дата: 05.07.23
В .Net я о стадиях сборки даже не думал. Знал что есть сборка и JIT-компиляция (вот там важно — иногда эта JIT-компиляция занимала 10 секунд, что удавалось решить Ngen-ом, причем важно было не перепутать битность платформы). А есть ли там какие стадии сборки — особо не думал об этом.
C C++, как оказалось, это критически важно и без этого даже не поймешь почему не работает прога. Думал хватит понимания что есть 3 стадии:
1. Препроцессор — раскрывает #include, #define, #if и пр.
2. Сам компилятор для каждого файла создает o-файл.
3. Линкер собирает все в единую библиотеку или exe-файл.
Оказалось что этого не достаточно, что видно из примера. Сейчас привожу максимально упрощенный пример, он из 3 файлов:
Файл demo.hpp
#pragma once
template <typename T>
class Checker
{
public:
Checker()
{
static_assert(sizeof(T), "Incomplete type");
}
};
class DerivedClass;
class BaseClass
{
public:
//BaseClass() {}
static void fun1();
private:
Checker<DerivedClass> m;
};Файл demo.cpp
#include "demo.hpp"
class DerivedClass
{
};
void BaseClass::fun1()
{
}Файл с функцией входа:
#include "demo.hpp"
int main()
{
BaseClass::fun1();
}Вопрос: почему если раскомментировать контруктор по умолчанию //BaseClass() {} — оно перестает компилироваться? Оказывается без понимания стадий сборки не поймешь этого. Тут чел. приводил стадии трансляции, возможно с этим тоже связано.
Честно сказать, даже доведя до мин. примера (общими силами), я не до конца понимаю почему возникает ошибка компиляции при явном консрукторе. Примерно так — если сборщик видит явный конструктор, то он уже не ищет реализацию класса DerivedClass а просто сразу отрабатывает assert. А вот если конструктор не указать явно, то почему assert не отрабатывает?
Вот положа руку на сердце — вы понимаете логику сбоки в этом случае?