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

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

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

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

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

 Mysticial23 мая 2012 г., 22:36
Ты можешь попытаться#define их в мусорный код, который не скомпилируется?
 chris23 мая 2012 г., 22:37
Не могли бы вы объявить их повторно?
 Steve Jessop23 мая 2012 г., 23:09
Я, наверное, неандерталец, но я просто пробовал в тестовом примере, который ищет источник дляGetProfileInt ...
 Nemanja Trifunovic23 мая 2012 г., 22:37
Что значит встроенный? GetProfile и т. Д. Встроены не более, чем для sqlite.
 SirPentor23 мая 2012 г., 22:38
Чтобы добавить к идее @ Mystical, #define GetProfile к чему-то вроде dont_us_get_profile_use_this_other_thing_instead.

Ответы на вопрос(5)

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

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

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

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

#define GetProfile  HAHA_Nice_try_This_will_not_compile!!!

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

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

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

#define GetProfileIntA InvalidFunctionDoNotCallMe

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

 Len Holgate23 мая 2012 г., 22:49
Вам не нужен распространенный включаемый файл, просто используйте / FI, чтобы принудительно включить файл во все файлы cpp. Вы можете установить / FI в файле проекта. Я писал об этом здесь: Lenholgate.com / блог / 2004/07 / ...
 Len Holgate24 мая 2012 г., 07:49
Стив, хорошая мысль. Я ожидаю, что ты прав.
 Mark Wilkins23 мая 2012 г., 22:52
@ LenHolgate: Хорошая информация. Я не знал об этом переключателе / FI.
 Steve Jessop23 мая 2012 г., 23:02
@ LenHolgate: не/FI включить файл вНачал каждого ТУ, правда? Так что#define также будет действовать в заголовке, гдеGetProfileIntA объявлено. В лучшем случае вы получите ошибку компоновщика, в худшем -GetProfileIntA - встроенная функция, и все еще работает!
 Gene Bushuyev23 мая 2012 г., 23:34
@ Len Holgate - мне действительно не нравится идея скрывать включаемые файлы в настройках проекта. В прошлом у меня было достаточно проблем с поиском вещей, которые люди переопределяли или скрывали от простого взгляда. Я бы предпочел включать заголовок везде, это небольшая цена за читабельность.
Решение Вопроса

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

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

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

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

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

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

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

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

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

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

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

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

#ifndef V2

void GetProfile()
{
  // Get the profile
}

void WriteProfile()
{
  // Write the profile
}

#endif

Ваш ответ на вопрос