скажите, я правильно понимаю, fopen_s() это M$ расширение?
смущает то, что гуглится и такое...
как вообще это использовать для разных компиляторов?
типа такого?:
#ifdef __STDC_WANT_LIB_EXT1__
# define my_fopen(h, p, m) \
std::fopen_s(&h, p, m)
#else
# define my_fopen(h, p, m) \
h = std::fopen(p, m)
#endif// __STDC_WANT_LIB_EXT1__
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Здравствуйте, niXman, Вы писали:
X>скажите, я правильно понимаю, fopen_s() это M$ расширение?
Было M$ расширение, теперь стало стандартом... точно не помню каким 11, 14 или 17...
так и как юзать сабж на разных платформах и компиляторах? тут пишут что если реализация опеределяет макропеременную __STDC_LIB_EXT1__. у меня она не определена, с++11.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Здравствуйте, Maniacal, Вы писали:
M>На stackoverflow вообще предлагают реализовать в виде функции
согласно этому, ошибку выдает сам компилятор. так что добавлением одноименной функции, думаю, проблему не решить. потому я и думаю, что может просто детектить M$-compiler и подсовывать ему именно std::fopen_s()?
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Здравствуйте, niXman, Вы писали:
X>скажите, я правильно понимаю, fopen_s() это M$ расширение?
Это опциональная функция языка C11. И по прежнему расширение в vc компиляторе (с чуть другим и нестандартным поведением).
X>как вообще это использовать для разных компиляторов? X>типа такого?: X>
X>#ifdef __STDC_WANT_LIB_EXT1__
X># define my_fopen(h, p, m) \
X> std::fopen_s(&h, p, m)
X>#else
X># define my_fopen(h, p, m) \
X> h = std::fopen(p, m)
X>#endif// __STDC_WANT_LIB_EXT1__
X>
В этом коде всё плохо :)
Судя по нему тут попытка смешать использование C и C++.
Но в стандарте С++ явно сказано про эту функцию из С (как и про многие другие), что они не определены в пространстве имён std.
X>#ifdef __STDC_WANT_LIB_EXT1__
Эта проверка тоже почти наверное ошибка. Этот макрос определяется пользователем. Он сам может задать его в любое целочисленное значение. Какой смысл его проверять?
В языке С эта функция будет доступна, если пользователь задал __STDC_WANT_LIB_EXT1__ в 1 перед первым включением stdio.h, а сама библиотека в свою очередь определила макрос __STDC_LIB_EXT1__.
Плюс в языке С++ наличие этих функций при включении любого C++ заголовочного файла — implementation defined. (с практической точки зрения это означает, что не стоит в С++ переиспользовать эти имена для своего кода — они могут конфликтовать с внезапно приехавшими определениями из какого-то случайного include).
Короче, тут в первую очередь стоит определиться на каком языке ты пишешь: на С или на С++. Ну и на какой версии. Это разные языки!
Здравствуйте, GhostCoders, Вы писали:
GC>Здравствуйте, niXman, Вы писали:
X>>скажите, я правильно понимаю, fopen_s() это M$ расширение? GC>Было M$ расширение, теперь стало стандартом... точно не помню каким 11, 14 или 17...
Здравствуйте, watchmaker, Вы писали:
X>>#ifdef __STDC_WANT_LIB_EXT1__ W>Эта проверка тоже почти наверное ошибка. Этот макрос определяется пользователем. Он сам может задать его в любое целочисленное значение. Какой смысл его проверять?
По стандарту, двойное подчеркивание в начале имени зарезервировано для реализации. И если такой макрос определяется пользователем, то плохо именно это.
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
ну да, fopen_s() — Си`шная функция.
остальные ошибки из-за спешки...
> В языке С эта функция будет доступна, если пользователь задал __STDC_WANT_LIB_EXT1__ в 1 перед первым включением stdio.h, а сама библиотека в свою очередь определила макрос __STDC_LIB_EXT1__.
а почему ты думаешь что в этом порядке?
мне почему-то кажется, что реализация должна определять __STDC_LIB_EXT1__, и только потом, юзер задетектив это, определяет __STDC_LIB_EXT1__. ну...согласно этому. но и тут все мутно...
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Здравствуйте, Ops, Вы писали:
Ops>По стандарту, двойное подчеркивание в начале имени зарезервировано для реализации. И если такой макрос определяется пользователем, то плохо именно это.
у меня есть такое правило: каждый макрос, который define`ится и undef`айнится в одном файле — может зваться как угодно(лишь бы без конфликтов), но макрос, который только define`ится — должен начинаться с двойного подчеркивания и префикса в виде имени проекта. посему, думаю, что в стандарте вряд ли найдется макрос с именем __YAS_*
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
#ifdef _MSC_VER
# define __YAS_FOPEN(h, p, m) \
::fopen_s(&h, p, m)
#else
# define __YAS_FOPEN(h, p, m) \
h = std::fopen(p, m)
#endif// _MSC_VER
код компилится M$-компилятором, но вот на первом тесте использующим ввод/вывод ловлю ошибку(appveyor): open file error
похоже, файл не открывается... нужно MSVC установить на машину...
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Здравствуйте, niXman, Вы писали:
X>у меня есть такое правило: каждый макрос, который define`ится и undef`айнится в одном файле — может зваться как угодно(лишь бы без конфликтов), но макрос, который только define`ится — должен начинаться с двойного подчеркивания и префикса в виде имени проекта. посему, думаю, что в стандарте вряд ли найдется макрос с именем __YAS_*
В стандарте покрыты все имена __*, так что это UB, хотя шансов, что оно когда-нибудь выстрелит, может и нет.
Each name that contains a double underscore __ or begins with an underscore followed by an uppercase letter is reserved to the implementation for any use.
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Здравствуйте, Ops, Вы писали:
Ops>Здравствуйте, watchmaker, Вы писали:
X>>>#ifdef __STDC_WANT_LIB_EXT1__ W>>Эта проверка тоже почти наверное ошибка. Этот макрос определяется пользователем. Он сам может задать его в любое целочисленное значение. Какой смысл его проверять?
Ops>По стандарту, двойное подчеркивание в начале имени зарезервировано для реализации. И если такой макрос определяется пользователем, то плохо именно это.
Если не троллишь, то советую посмотреть rationale для этого изменения: http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1173.pdf
Или заглянуть в стандарт, где есть примеры правильного кода, где именно в пользовательском коде определяется значение макроса.
Имя __STDC_WANT_LIB_EXT1__ действительно зарезервировано в стандарте языка C. И зарезервировано оно именно для пользовательского использования (как, вообще говоря, задумано и для всёго семейтсва __STDC_WANT_*).
Если пользователь его определил и его значение 0, то секция Annex K из стандарта не действует. Если определил и его значение 1, то становятся доступны определения из секции Annex K (при условии, что реализация в свою очередь выставит __STDC_LIB_EXT1__). Если макрос __STDC_WANT_LIB_EXT1__ не определён пользователем, то реализация может на своё усмотрение трактовать его значение как 0 или 1 (implementation defined).
Почему для макроса __STDC_WANT_LIB_EXT1__ было выбрано имя из зарезервированного пула имён?
Как раз по той причине, что эти имена уже были зарезервированы. И следовательно в корректном пользовательском коде они не должны встречаться. А значит вводя новое имя макроса в новой версии языка нет риска сломать обратную совместимость.
Здравствуйте, niXman, Вы писали:
X>именно.
А точно разумно использовать в переносимом коде специфические функции и городить из них огород, если есть одинаковые? На мой взгляд, предупреждения недостаточная для этого причина.