Сообщение Re[3]: При портировании кода на линукс столкнулся с проблемо от 09.08.2019 12:08
Изменено 09.08.2019 14:07 watchmaker
G6>Здравствуйте, watchmaker, Вы писали:
W>>Обе проблемы решаются исправлением кода в соответствии со стандартом языка:
printf( "%u--%s--%u", 0x55, c0.m_Pointer, 0xAA);
G6>Можно ссылочку в стандарте на эту часть?
Важны эти пункты:
То есть нет гарантий работоспособности передачи такого типа через .... То есть это заведомо непереносимо, т.к. "implementation-defined semantics" может быть UB или отказом от компиляции.[expr.call]
When there is no parameter for a given argument, the argument is passed in such a way that the receiving
function can obtain the value of the argument by invoking va_arg
...
Passing a potentially-evaluated argument of class type (Clause 12) having a non-trivial copy constructor, a non-trivial move constructor, or a non-trivial destructor, with no corresponding parameter, is conditionally-supported with implementation-defined semantics.
Но если если "implementation-defined semantics" устраивает для известного множества версий компиляторов (например, как в gcc), то формально писать так можно.
clang тут прав.
gcc, с разным способом передачи в зависимости от наличия конструктора, тоже прав.
А вот чтение параметра не того типа — уже всегда UB:
printf будет читать в соответствии с спецификатором %s, а нужно только с va_arg(…, ttt<char>) (ну и при условии предыдущего пункта).[cstdarg.syn]
If the parameter parmN is of a reference type, or of a type that is not compatible with the type that results when passing an argument for which there is no parameter, the behavior is undefined.
G6>Здравствуйте, watchmaker, Вы писали:
W>>Обе проблемы решаются исправлением кода в соответствии со стандартом языка:
printf( "%u--%s--%u", 0x55, c0.m_Pointer, 0xAA);
G6>Можно ссылочку в стандарте на эту часть?
Важны эти пункты:
То есть нет гарантий работоспособности передачи такого типа через .... То есть это заведомо непереносимо, т.к. "implementation-defined semantics" может быть UB или отказом от компиляции.[expr.call]
When there is no parameter for a given argument, the argument is passed in such a way that the receiving
function can obtain the value of the argument by invoking va_arg
...
Passing a potentially-evaluated argument of class type (Clause 12) having a non-trivial copy constructor, a non-trivial move constructor, or a non-trivial destructor, with no corresponding parameter, is conditionally-supported with implementation-defined semantics.
Но если если "implementation-defined semantics" устраивает для известного множества версий компиляторов (например, как в gcc), то формально писать так можно.
clang тут прав.
gcc, с разным способом передачи в зависимости от наличия конструктора, тоже прав.
А вот чтение параметра не того типа — уже UB, кроме случаев
printf будет читать в соответствии с спецификатором %s, а нужно только с va_arg(…, ttt<char>) (ну и при условии предыдущего пункта).— one type is a signed integer type, the other type is the corresponding unsigned integer type, and the value is representable in both types;
— one type is pointer to void and the other is a pointer to a character type.