std::cout breaks after nullptr
Marc Glisse
marc.glisse@inria.fr
Mon Mar 25 11:37:00 GMT 2019
On Mon, 25 Mar 2019, Jonathan Wakely wrote:
> On Sun, 24 Mar 2019, 13:53 Xi Ruoyao, <xry111@mengyan1223.wang> wrote:
>>
>> On 2019-03-24 12:45 +0000, Jonny Grant wrote:
>>> Hello!
>>>
>>> Is this an issue? G++ doesn't identify problem in this test case doesn't
>>> when compiling or running.
>>>
>>> "hello" is not displayed, std::cout never works again after nullptr.
>>>
>>>
>>> // g++-8 -Wall -Wextra -Wconversion-null -Wno-nonnull-compare
>>> -Wzero-as-null-pointer-constant
>>> -fsanitize=null,returns-nonnull-attribute,signed-integer-
>>> overflow,leak,undefined,address
>>> -o cout cout.cpp
>>> #include <iostream>
>>> int main()
>>> {
>>> const char * p = nullptr;
>>> std::cout << p;
>>> std::cout << "hello";
>>> }
>>
>> The standard *Requires* p is not a null pointer here (N4618 27.7.3.2.4 p3). So
>> if p is a null pointer, the implementation (GCC and libstdc++) can do anything.
>>
>> Libstdc++ is friendly. It does not abort, raise exception, or run
>> /usr/game/starwar, it just sets ios::badbit to cout (ostream:559) so actually
>> you can detect this issue by checking the state of cout.
>
>
> And you can use it for more output after clearing the badbit flag.
>
>> But do NOT rely on
>> this behavior. This is really undefined.
>>
>> Because libstdc++ is so friendly, the sanitizer don't even know this is an
>> undefined behavior. And, it can not sanitize undefined behaviors in
>> libstdc++.so because it was built w/o -fsanitize= option.
>>
>> Well, if you want this to be detected at compile time, maybe you can convince
>> Jonathan to add an __attribute__((nonnull(2))) to operator<<(basic_ostream&,
>> const char *). Then this case can be detected with "-O -Wnonnull".
>
>
> That seems like a good idea.
Note that IIRC the attribute is also used for optimization purposes.
Adding it would remove the test "if (!__s)". One could try and add the
attribute only for user code and not while compiling the library itself,
but that's getting complicated (_GLIBCXX_EXTERN_TEMPLATE, specializations
for types other than char, etc).
--
Marc Glisse
More information about the Gcc-help
mailing list