Dev C++ strtok_s throws [Предупреждение] назначение делает указатель из целого числа без приведения

У меня есть следующая программа:

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) 
{
   char *tp = NULL, *cp = NULL, *next_token = NULL;
   char TokenListe[] = "Hello,I Am,1";

   tp = strtok_s(TokenListe, ", ", &next_token);

   printf(tp);
   return 0;
}

Когда я компилирую его с помощью Visual Studio 2015, он компилируется без каких-либо предупреждений. Но когда я скомпилирую его с помощью Dev C++ 5.11, я получаю следующее предупреждение в строке 10:

[Внимание] присваивание делает указатель целым без приведения

Есть ли решение исправить это предупреждение?


person Community    schedule 02.03.2018    source источник
comment
strtok_s в Visual Studio не соответствует стандарту C11 strtok_s - принимают разные параметры, отсюда и предупреждение. И в C++ вы не должны использовать массивы char или строковые функции C   -  person UnholySheep    schedule 02.03.2018
comment
Вы компилируете как C++ или как C? Если C, если Dev C++ не имеет нестандартного strtok_s, он будет неявно объявлен и предполагается, что он возвращает целое число. Получаете ли вы другие ошибки, такие как implicit declaration of function 'strtok_s' или (при связывании) undefined reference to `strtok_s'?   -  person Thomas Padron-McCarthy    schedule 02.03.2018
comment
Я компилирую как C   -  person    schedule 02.03.2018


Ответы (3)


Начиная с C11, strtok_s теперь является стандартным C, частью дополнительного «интерфейса проверки границ» (Приложение K). Компиляторы не должны его поддерживать.

Но если да, то формат такой (C11 K.3.7.3.1):

#define __STDC_WANT_LIB_EXT1__ 1
#include <string.h>

char *strtok_s(char * restrict s1,
               rsize_t * restrict s1max,
               const char * restrict s2,
               char ** restrict ptr);

Любой другой формат является нестандартным мусором и не должен использоваться, в том числе Microsoft strtok_s.

Dev C++ больше не поддерживается и поэтому содержит только очень старую версию gcc. Он не поддерживает C11, но, насколько мне известно, ни одна из более новых версий библиотек gcc + не поддерживает интерфейс проверки границ C11. Visual Studio является некондиционным компилятором и не может использоваться для компиляции стандартного C. В общем, я бы посоветовал не использовать ни один из этих компиляторов, а обновиться до новой версии gcc (например, Codeblocks с Mingw).

Резюме: strtok_s нельзя использовать разумным образом. Вместо этого используйте strtok. Просто убедитесь, что все задействованные буферы достаточно велики и не могут быть переполнены. В случае многопоточной программы просто не используйте strtok вообще.

person Lundin    schedule 02.03.2018

Если Dev C++ не имеет нестандартного strtok_s, в C он будет неявно объявлен и предполагается, что он возвращает целое число.

Примечание: strtok_s есть в стандарте, но как «необязательное расширение», согласно (моей бесплатной черновой копии) стандарта C11.

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

Если Dev C++ содержит реализацию strtok_s и ссылки на нее, объявление ее самостоятельно может сработать. Но лучший вариант — найти правильный заголовочный файл или флаги компилятора, чтобы объявить его, если такие параметры существуют. Обратитесь к документации.

Но обратите внимание, как заметил Майкл Вальц, что strtok_s в стандарте C11 и strtok_s от Microsoft различны и не имеют одинаковых параметров! Я не знаю, какую версию реализует Dev C++.

person Thomas Padron-McCarthy    schedule 02.03.2018
comment
Так я объявил это для себя, чтобы избежать предупреждения? - person ; 02.03.2018
comment
Если функции strtok_s нет, объявление ее не поможет. - person Thomas Padron-McCarthy; 02.03.2018
comment
Если Dev C++ действительно содержит реализацию strtok_s и ссылки на нее, то да, ее объявление будет (вероятно) работать. Но лучшим вариантом, вероятно, будет найти правильный заголовочный файл или флаги компилятора, чтобы объявить его. - person Thomas Padron-McCarthy; 02.03.2018
comment
Существует существует стандартная функция strtok_s, но он отличается от Microsoft strtok_s - person Jabberwocky; 02.03.2018
comment
Dev C++ больше не поддерживается. Они перестали поддерживать его задолго до C11, поэтому он не соответствует этому стандарту. Как и Visual Studio. - person Lundin; 02.03.2018

Основываясь на ответе от @thomas-padron-mccarthy, я мог решить свою проблему с объявлением функции strtok_s в моем заголовочном файле.

extern char* strtok_s(char*, char*, char**);
person Community    schedule 02.03.2018
comment
Это заставит предупреждение исчезнуть, но либо вызовет ошибки компоновщика, либо приведет к сбою и сгоранию вашей программы. - person Lundin; 02.03.2018
comment
Моя программа не падает. Но есть ли другое решение? - person ; 02.03.2018
comment
@k.Lennartz, если ваша программа не падает, возможно, вам повезло. У вас есть три чистых варианта: 1. Используйте не strtok_s, а strtok. 2. Найдите реализацию strtok_s (с Google это не должно быть сложно) и используйте эту. 3. Полностью отказаться от Dev C++ и использовать что-то другое. - person Jabberwocky; 02.03.2018