This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Passing 0 for number of bytes to be scanned in memchr


Thanks for the explanation. It was very helpful. I was trying to figure out if we can just call memchr without checking n==0. Now it is clear we cannot.


Thanks
-Aditya




From: Jonathan Wakely <jwakely@redhat.com>
Sent: Thursday, February 16, 2017 7:21 AM
To: Aditya K
Cc: libstdc++@gcc.gnu.org
Subject: Re: Passing 0 for number of bytes to be scanned in memchr
    
On 16/02/17 12:40 +0000, Aditya K wrote:
>> If __s is a null pointer then passing it to memchr is undefined.
>
>That means we are missing the check when __s == nullptr?

No.

>I also wanted to know what happens when __n is zero in the case of memchr. I think memchr returns null in this case so we can remove that check.

No. I understood what you were asking, and I answered it.

Think about the inputs to the function.

memchr(nullptr, 'a', 0) is undefined behaviour.
char_traits<char>::find(nullptr, 0, 'a') is allowed.

How do we support the find(nullptr, 0, 'a') case but ensure we don't
pass a nullptr to memchr?

I can think of two ways, either we check for s==nullptr or we check
for n==0. So is there a reason to prefer one not the other?

Currently we check n==0, and it works fine.

You seem to be suggesting that we remove the n==0 check and add an
s==nullptr check. That would not be an improvement.

char_traits<char>::find(nullptr, 1, 'a') is not allowed, because it would
try to read from a null pointer.

If we checked for s==nullptr then we would return a null pointer for
find(nullptr, 1, 'a') as though it was a valid function call, but it
isn't. We would hide a bug in the program and prevent sanitizers from
diagnosing it.

If we check for n==0 we avoid passing null to memchr, and we also
avoid even calling memchr when we know what the answer will be.

We could call memchr in the case where s!=nullptr and n==0, and let
memchr handle the n==0 case, but why would that be an improvement?



>
>Thanks,
>-Aditya
>
>
>
>
>From: Jonathan Wakely <jwakely@redhat.com>
>Sent: Thursday, February 16, 2017 6:12 AM
>To: Aditya K
>Cc: libstdc++@gcc.gnu.org
>Subject: Re: Passing 0 for number of bytes to be scanned in memchr
> 
>On 16/02/17 11:38 +0000, Aditya K wrote:
>>Hi Jonathan,
>>
>>I see that in char_traits<char>::find, we check if the number of bytes to be scanned is zero. I think memchr handles that case already but I do not have
>>
>>any reference to point out to. The documentation does not explicitly mention what happens when 'n' is zero. If n==0 is already handled then
>>
>>we can safely remove this check. Please let me know your thoughts.
>>
>>
>>269       static const char_type*
>>270       find(const char_type* __s, size_t __n, const char_type& __a)
>>271       {
>>272         if (__n == 0)
>>273           return 0;
>>274         return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n));
>>275       }
>
>If __s is a null pointer then passing it to memchr is undefined.
>
>I'm not 100% sure, but I don't think basic_string::find has the same
>restriction, so we need to handle the case where it's null and avoid
>calling memchr.
>
>
>
    

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]