Избавьтесь от предупреждающего сообщения - правильный способ

Я работаю над устаревшим кодом pro * C/C++ и перенес проект в Visual Studio 2015. Когда я компилирую код в VS, он выдает мне предупреждающее сообщение ниже более чем в 100 местах.

warning C4267: '=': conversion from 'size_t' to 'unsigned short', possible loss of data

и соответствующий код

stmt.len = strlen((char*)stmt.arr); // VARCHAR stmt[500];

Я планировал изменить приведенный выше код на

stmt.len = static_cast<unsigned short>(strlen((char *)stmt.arr));

это просто удалит предупреждающее сообщение. Но я должен изменить более чем в 100 местах. Есть ли способ избавиться от этого предупреждающего сообщения, возможно, с помощью какого-то макроса? Пожалуйста, предложите.

Спасибо


person NJMR    schedule 14.11.2017    source источник
comment
@NJMR Если вы можете просто повторно объявить член данных stmt.len как имеющий тип size_t. :)   -  person Vlad from Moscow    schedule 14.11.2017
comment
Изменить тип члена len?   -  person Some programmer dude    schedule 14.11.2017
comment
И приведение типов в стиле C, как вы делаете с (char*)stmt.arr, обычно является признаком того, что вы делаете что-то неправильно.   -  person Some programmer dude    schedule 14.11.2017
comment
@VladfromMoscow: VARCHAR — это профессиональный тип данных C/C++. Я не могу его изменить.   -  person NJMR    schedule 14.11.2017


Ответы (2)


Вы можете отключить предупреждение с помощью

#pragma warning( disable : 4267)

хотя лично я бы проработал ошибки и исправил правильно. Ваша идея с static_cast неплоха, и нет опасности неопределенного поведения с переполнением, поскольку вы используете типы unsigned.

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

person Bathsheba    schedule 14.11.2017
comment
ты тоже заслуживаешь :) - person oetoni; 14.11.2017
comment
Но я должен измениться более чем в 100 местах. Есть ли способ заменить strlen с помощью макроса, чтобы вернуть unsigned short? - person NJMR; 14.11.2017
comment
@ Вирсавия Нет! ты был быстрее меня! это все, ты должен быть первым - person oetoni; 14.11.2017
comment
@HJMR вот решение этого (официальное) msdn.microsoft.com/en- us/library/jj715718.aspx (другой поток) stackoverflow.com/questions/12884331/ - person oetoni; 14.11.2017

Это правильный способ последовательного использования size_t. Или там делайте отливки, которые вы хоть как апдейт.

Обходной путь для предупреждений C4267 и способы их отключения также предложены есть умный-способ-исправить-многие-c4267-предупреждение-преобразование-из-размера-в-целые-или-другие-типы?forum=vclanguage" rel="nofollow noreferrer">здесь:

#pragma warning (disable : 4267)

Для макроса #define (только образец)

#include <iostream>
#include <string.h>
#define strlen(x) static_cast<unsigned short>(strlen((char *)x)) 
//I tested with ((char *)x+1) and ((char *)x+2) for variation

using namespace std;

int main() {
    char stmt[] = "something";
    int len = strlen((char*)stmt); // VARCHAR stmt[500];
    cout << len;
    return 0;
}

Протестируйте здесь с помощью IDEONE

person oetoni    schedule 14.11.2017
comment
нет и спасибо. Я также видел, что вы ответили намного быстрее, чем я :D - person oetoni; 14.11.2017
comment
@oetoni: Итак, я добавил это. #define strlen(x) static_cast‹unsigned short›(strlen((char *)x)). Пожалуйста, поправьте меня, если я ошибаюсь. - person NJMR; 14.11.2017
comment
вам действительно не следует делать макрос с #define. как сказал @Barthsheba, это не определенное/задокументированное решение для вашего сценария, а ваш выбор ... если вы решите это сделать, то вы правы в определении макроса. Это сработало бы. Я добавляю пример кода и тестирую свой ответ - person oetoni; 14.11.2017