Вопрос по visual-c++, visual-studio-2010, c++ – Могу ли я вызвать ошибку компилятора при вызове определенных функций?

12

У меня есть версии моего программного обеспечения v1 и v2. v1 использует реестр для сохранения настроек, с множеством вызовов GetProfileInt и т. д. v2 теперь использует sqlite db для сохранения настроек.

В настоящее время мы разрабатываем обе ветви и объединяем новые функции из ветки v1 в ветку v2. В настоящее время мы должны помнить, чтобы обновлять любые вызовы реестра, чтобы использовать новую конфигурационную базу данных, и это было пропущено несколько раз.

Я хотел бы выдать ошибку компилятора, если какая-либо из функций GetProfile ... или WriteProfile ... используется в v2.

Мы используем C ++ в Visual Studio 2010. Если ничего не встроено, могу ли я использовать выходные данные из скрипта, чтобы как-то выдать ошибку компилятора?

Не могли бы вы объявить их повторно? chris
Чтобы добавить к идее @ Mystical, #define GetProfile к чему-то вроде dont_us_get_profile_use_this_other_thing_instead. SirPentor
Я, наверное, неандерталец, но я просто пробовал в тестовом примере, который ищет источник дляGetProfileInt ... Steve Jessop
Что значит встроенный? GetProfile и т. Д. Встроены не более, чем для sqlite. Nemanja Trifunovic
Ты можешь попытаться#define их в мусорный код, который не скомпилируется? Mysticial

Ваш Ответ

5   ответов
12

я мог бы также включить решение, которое фактически использовал спрашивающий:

jacobsee обнаружил устаревшая прагма

#pragma deprecated(GetProfileInt)
Оригинальный ответ:

Вы можете объявить их устаревшими, используя__declspec(deprecated). Это будет выглядеть так:

UINT __declspec(deprecated) WINAPI GetProfileInt(
  __in  LPCTSTR lpAppName,
  __in  LPCTSTR lpKeyName,
  __in  INT nDefault
);

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

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

В качестве альтернативы можно поместить объявление функции в анонимное пространство имен, и, если оно называется компилятором, оно сообщит о неоднозначности. Gene Bushuyev
Просто к твоему сведению,cl имеет опцию/FI, который можно использовать для включения заголовка без изменения какого-либо источника, может быть полезным здесь:/FImydeprecated.h hmjd
Я попробовал твой код, и он у меня не сработал. Я получил ошибку компоновщика dll. Затем попытался поставить WINBASEAPI впереди, и это скомпилировано. Это хочет соответствовать версии SDK против версии CWinApp, я думаю ?? Но тогда он не смог обнаружить мое использование AfxGetApp () -> GetProfileInt. Но я нашел решение, которое прекрасно работает: просто добавьте устаревший #pragma (GetProfileInt) в глобальный заголовочный файл. Я сделал то же самое для GetProfileString, WriteProfileInt, WriteProfileString. Благодарность jacobsee
Спасибо за обновленный ответ, ура! jacobsee
Вот ссылка, которая привела меня к ответу: Weseetips.com / 2008/12/22 / ... jacobsee
3

Вы можете использовать макрос для переопределения их во что-то, что не будет компилироваться:

#define GetProfile  HAHA_Nice_try_This_will_not_compile!!!

Подвох в том, что вам нужно убедиться, что он (законно) не вызывается вне вашего кода.
(Так что вы должны поместить макрос после всех ваших включений.)

Macros, как правило, плохая идея, она будет выполнять текстовую подстановку везде, даже если кто-то имеет допустимое имя GetProfile, скажем, как функцию-член. Намного безопаснее объявлять функции, а не макросы. Gene Bushuyev
Хорошая точка зрения. Я забыл рассмотреть функции-члены. Хотя, кроме ответа bames53, я не могу придумать, как можно вообще переопределить функцию и заставить ее скомпилировать? Mysticial
@ Mystical: вы можете использовать анонимное пространство имен вместоdeprecated Gene Bushuyev
@ GeneBushuyev Ооо ... это сложно! :) Я пытался придумать что-то вроде неоднозначной перегрузки. Но взломать пространство имен лучше! Mysticial
1

вы можете добавить что-то вроде этого (с помощьюW илиA при необходимости). Это приведет, по крайней мере, к ошибке компоновщика (предупреждение / ошибка компилятора будет зависеть от флагов):

#define GetProfileIntA InvalidFunctionDoNotCallMe

Windows уже определяет такие функции, какGetProfileInt как макросы для версий A или W.

Вам не нужен распространенный включаемый файл, просто используйте / FI, чтобы принудительно включить файл во все файлы cpp. Вы можете установить / FI в файле проекта. Я писал об этом здесь: Lenholgate.com / блог / 2004/07 / ... Len Holgate
@ LenHolgate: Хорошая информация. Я не знал об этом переключателе / FI. Mark Wilkins
@ LenHolgate: не/FI включить файл вНачал каждого ТУ, правда? Так что#define также будет действовать в заголовке, гдеGetProfileIntA объявлено. В лучшем случае вы получите ошибку компоновщика, в худшем -GetProfileIntA - встроенная функция, и все еще работает! Steve Jessop
@ Len Holgate - мне действительно не нравится идея скрывать включаемые файлы в настройках проекта. В прошлом у меня было достаточно проблем с поиском вещей, которые люди переопределяли или скрывали от простого взгляда. Я бы предпочел включать заголовок везде, это небольшая цена за читабельность. Gene Bushuyev
Стив, хорошая мысль. Я ожидаю, что ты прав. Len Holgate
0

#define GetProfileInt(a, b, c) "don't use this"; после#include 'ingWindows.h.

ПосколькуGetProfileInt - это макрос для маршрутизации к нужной функции, это приведет к переопределению макроса. И с тех порchar[] нельзя назначитьUINT, компиляторerror S.

Хотя это грязный, грязный хак, мне хочется принять душ, чтобы обсудить это.

1

но это не совсем соответствует тому, что задает вопрос, по двум причинам:

Это только предупреждение, но не ошибка. Он выдаст предупреждения, даже если вы используете код v1.

Есть веские причины этого хотеть, но на самом деле это не то, о чем просит оригинальный вопрос.

К счастью, есть действительно простой способ получить то, о чем спрашивают вопросы. Компилятор всегда выдаст ошибку, если функция просто не существует. Просто бросьте функции в#ifndef.

#ifndef V2

void GetProfile()
{
  // Get the profile
}

void WriteProfile()
{
  // Write the profile
}

#endif

Похожие вопросы