Есть ли способ предотвратить использование нереализованных функций во время компиляции?

часто я сталкиваюсь с такими хаки

//lets say this is some class that still doesnt support...
//...all the functionality that it should based on the design docs
void MyClass::MyFunction()
{
throw std::exception("not implemented");
}

Я думаю, это плохая практика, но это в стороне:
Есть ли способ сделать то же самое во время компиляции, но только если функция используется (иначе, если она не используется, компиляция должна завершиться успешно).

Редактировать: я также заинтересован в виртуальных функций мем.

0

Решение

Если это не виртуальная функция, вы можете просто закомментировать определение.

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

4

Другие решения

Если вы полностью удалите реализацию и будете иметь только объявление функции, возникнет ошибка компоновщика, которая обычно составляет время компиляции. К сожалению, ошибки компоновщика имеют тенденцию быть уродливыми и их трудно отследить, но в случае вызова функции, которая еще не была реализована, я думаю, что они довольно управляемы.

6

Старый вопрос, но все же …

Я использую пару простых помощников для этого. Это даст ошибку ссылки, которая довольно читабельна:

// Not implemented is not implemented :-)thing, it'll break:
struct NotImplHelper { static void notimplemented(); };
#define notimplemented() NotImplHelper::notimplemented();
#if defined(DEBUG) || defined(_DEBUG)
#define notimplementedvirtual() throw std::exception();
#else
#define notimplementedvirtual() static_assert(false, "You should implement virtual function calls before moving to production.");
#endif

Использование:

//lets say this is some class that still doesnt support...
//...all the functionality that it should based on the design docs
void MyClass::MyFunction()
{
notimplemented();
// or notimplementedvirtual() if MyFunction() is virtual...
}

Обоснование:

ИМХО, если вы используете функцию в своей программе, она должна быть доступна. Когда вы пытаетесь скомпилировать что-то, что вы еще не реализовали, это должно привести к ошибке времени компиляции или компоновки.

Например, в MSVC ++ это даст:

1>Test.obj : error LNK2019: unresolved external symbol "public: static void __cdecl NotImplHelper::notimplemented(void)" (?notimplemented@NotImplHelper@@SAXXZ) referenced in function "[blahblahblah]"

Обратите внимание, что «ссылочная функция» есть в MSVC ++. Я не проверял это в других компиляторах.

Что касается нереализованных вызовов виртуальных функций, единственное, что у вас есть, это выбросить исключение. Не иметь возможности реализовывать их в своем отладчике во время разработки — это нормально, однако в тот момент, когда все становится серьезно, они могут вызываться вашей программой, поэтому они должны быть доступны. static_assert обеспечивает последнее. (Итак: в сочетании с любым пакетом непрерывной интеграции он в основном потерпит неудачу.)

Очевидно, что большинство людей случайно перепутают notimplemented а также notimplementedvirtual, На самом деле это не большая проблема: простое решение — всегда использовать первое, если только вы не хотите избавиться от ошибки, потому что это WIP.

1

Самое простое решение, которое я могу придумать, это прокомментировать невыполненную функцию.

Может быть, не то, что вы имели в виду, но при этом произойдет ошибка времени компиляции, если что-то попытается его использовать, и полученный код должен быть идентичен пустой функции, которая обычно оптимизируется.

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector