From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from sonic305-20.consmr.mail.ir2.yahoo.com (sonic305-20.consmr.mail.ir2.yahoo.com [77.238.177.82]) by sourceware.org (Postfix) with ESMTPS id 2A81E385801A for ; Sat, 27 Mar 2021 14:58:35 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 2A81E385801A X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1616857113; bh=rp8sKXnZPmolAO5EsUHKq2AyEKBDq07F+cLwAacbzJf=; h=X-Sonic-MF:Subject:To:From:Date:From:Subject; b=SYtwnMH3m8ecEgp9bf3kjZPjt0NpGVf6PwR2fcg730XG1MMGpgmuG+CZe/K93i1MuzZSHBvGeNwcftOFhdMfY2hmujiCwKH8DagWAW9d09djV4Tc/zStEseHI0qPKyEQY+O1QE80Vsism/5RiZkEqOfvgTx+3JA4xtTdZEsomFimUg5fB6mkl5XHbP6Pea3xCzMG6pCmTmJ/bq3LObNxJEzuTQP7ckVDRGWLKF+2+N+6eXxrQpcOsJD20YxpElouT4AyJkIn3MYTrS/+uIkifZBDwVlDbLr0jl2eKtqRO0zWNokUhoZX1pDV2Xnu9i8qukMgfxcGv7cbPNaoYSh76w== X-YMail-OSG: tOpAM1wVM1lEiBPAR2SClymbSPNMO8xjYXgjmCZSmmsFpiKkmf8jl6A7m0qLS4H CVHyNSesZ4l_dsfI6sdXYWdGKNBmT_XjGajA1fLTxhZjaRTxPAR94iRId1Cegr0opneNg6HTOqPU TovxpaOBrMN3DxKxQmAbUhTOvTYFMrYQATce9K.CdpQJEZh8cE3wfHBe.w3MADkzKSFrN3Jtcarz aAem6NxTrdmVNcBZsDZeBiYnCmRHYhupkidp2AQ.TanOIMwpupqD5vb9.Wj1HNNXXMUacMwcC43y vu.LqBF7PCovQ0C3Ctf_RSNYtThuEr_MzWcWgx34skjNR0l5WLpEL5IVYVeIpe4_xoUf5gti1CS. r4_hI0vLRiupvJGi_Sg.6pfNkzj4kQpF.M_1CTXhVcbGgHqKtryzTp998cAaTjEHrPdwmv2B5Qxe 20kHXVCAKTZwAKgBrkeiDsln.7NBS.gqDOpv2Uv6ND3Dwg.zH58breZBUGaq_WJF.ZLeW44MZz34 Ox5gdL8QX2vhVgtgo5aB0.gIcynZqY6nx.TOC4DEYXs0lISHI1T9Efq0FX_YMSW0Q64yFmStaPMU 7bCuJ.aI3LE2GiAa9vcfQ7EYzlmr9UjCBsQxU4ihMtNksomH0Yl2.TOr2KFqpNMJgl2_V6bKwal8 gKidYTi2s6DPSrAKIOIz7hbmZlHaPzwDZ5s8AwRqbBoAH6Mhoi93ZpuPFG6B3Wo8N1zZ2EmB74rv YkvxHMbTFCJOBHvHhvsgNXJF_NVU4qqAVfmMUCFuiUmsrveAZQ2j3ubTORpaQDBPAOtrK6JGr8_B .5U2JCcZQGjkuFjQpiVrmV8Ech2PMFgZtuMibLyrt03vCL8jwp5DxCAG1jCave29En5L2zXUKr8X KTx1Z.CMflSFebUma2paimuQKbHGlS8pjJQOCdHSlEOxSYXa25yWjRUn.24qLidkF2ONJIMLfBp4 3ja9MqmTG.2SwpQOTRxYsMPZv_W4H9FCtiLh2VZOzLVOaXNcXsbNFN6pU2e5nVFPCuOdKMj4__jE Osi5XzXsPRnHnU5TZ75v6BHpigd45u5hXmooIG.xJmnpsdCo_E1qAB5ZPDzWWKaR5cFe2xxMvbv5 CNXeEDL4BA9YR8EWHfpSLW7lgtFU9.oI2_CxT0G3qX8jlPCi2jhfAl3rr1.9Wyo3OY_QcR2hGz0U jGkGFjmzLw3liaQkg3IyyRl1HYAaE6fSF767qoBzgr7pLg33tZ_r_J2rOP14pvSfV0No_UFnOYB9 zy0EVAdo6EwwulWj2sNyN_Tx7xgKEVihjXevCquDdZYUD9AtdfAf5f2KxIEV9mMK5xJVep32lY_N 0IW6M9HeaQKzOVE11y7tYQkfLSP33hWUcPTEC6dyfn9oOKifqCdmOnVAItSEwAbVhY0Pu8kLL4ig z146kSgAzktOxiIjuqmSfaozM6yj9mpkjIU.B6Lvc9DZmsuq.Z.IPhkiUYuCCQmMiEyZ0oY_nrZo 6wNCf3DxuNPO08PKflGsDe1tX2WiY6hOy1lUqvoXc4DxwOqncml3uJ2RnYANjYga3KWIwGyfCuxP azXM6Gzn0q.OFySBSyVHBYgHxkUB80R3R3rS.pcPXlsRTLnHuv5MQzaz3EY3IEodAIlVlVP2oI8a qTD85zy.GD.KhiZMT3lkaPDL7LRQ6mUIN9drjYUwWE1vCvpdOXTkM0PuhdUQjfeoMHorY_cih_Oy cmLXdszOSCTbtZRFnVr7ZQ.JjPHSP1hvoUytSQrSVL1z5HTE5cQpc_hfflPOIA8fc3eDbQs8DEWI ZDZfbmt2honYCE4yIgeBwI0dZPB.GZph0YTenG0ecyjeAO02KU4Vssamje7J4TnyEAnjjVhQc_qe JeKdiJJuxGMoPaNJVQ4qX5XjHZEPWgdHRDQQaTpBVCUVuKnhKa3erQ4FTPVfnSu0hqBGR1m8CANL 0jqyyYoIfrefMt1clLJFGMHA5mbCXTtGWHz2tPx9YAhc0QKnpNTvb7fIxamB53xKlKUVySfu2JxY SyN9a1nsXwxEfFa.Z8XK4.AtJUfATEY5F9CU58gzak.X9pq3cYeQVZ9.BmIxYu_W1hJNoLDUaA_0 qGQBXnTZ.qHBIuudbreIY0S_aQCgn8LonrkYkFfwZfWPTR5GJwJO.LYKjsGQ.JZd5jSbtcz6VwcH jCtLcxCvhZhzy7LGFBUOXcOa3OC92.jH2oneVGz3R_2g74Gnv5B0rks1udxQN.rj1clOkcDSa.mr JdgTzrOh9D2DSYd3rh4M1fwlQN2sfHJIEiLXUptvNt1P483F8EEV_119tRbsE4R5FubfLXr.WzDo 6sHza5WdLlnDD_bAS3.yBeRJMQ3qAkVmkGFh3siF.n8HhBR0PNuxNZQoaeps.ADLQDUJhGLER_nF 9RBdij1VXkUs5Y85erKbBHRK5nzyARmoF6ng_oLrCvP3QWz..eaqDhoFLlFVWiR4UpYKaQE8uiNQ _qYL6xMe9cICrK5Ay4wWdFMzH90MWfwCM4gTDszaBC3OgMY66DmQU2m0x_6ENhHce_TbHzGQ- X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic305.consmr.mail.ir2.yahoo.com with HTTP; Sat, 27 Mar 2021 14:58:33 +0000 Received: by smtp405.mail.ir2.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 7e98119a5f3cd30a646335e9263f039b; Sat, 27 Mar 2021 14:58:29 +0000 (UTC) Subject: Re: Questions about std::string::operator=(char) To: Jonathan Wakely Cc: libstdc++ References: <7eeb24bf-58cc-5316-807e-64434ecf4b83.ref@yahoo.fr> <7eeb24bf-58cc-5316-807e-64434ecf4b83@yahoo.fr> From: tika Message-ID: Date: Sat, 27 Mar 2021 15:58:28 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.8.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Content-Language: en-US X-Mailer: WebService/1.1.17936 mail.backend.jedi.jws.acl:role.jedi.acl.token.atz.jws.hermes.yahoo Apache-HttpAsyncClient/4.1.4 (Java/11.0.9.1) X-Spam-Status: No, score=0.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, KAM_ASCII_DIVIDERS, NICE_REPLY_A, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=no autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libstdc++@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libstdc++ mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 27 Mar 2021 14:58:36 -0000 I understand.  I do not think there is a bug in the STL, only a grey area. My primary concern is the detection of the bug in my (the user) code in unit testing.  That's the bug I mean in the 'bug detected!' comment. A warning by the compiler would be nice and sufficient to avoid most cases of this mistake, which unit testing can detect like this:     std::string s;     s = some_function_returning_int_0();     EXPECT_EQ(s, s.c_str()); Which makes it seem UB is involved.  And the fact that the MS STL handles the case differently, with a warning, which is nice, and providing a different result (making s zero length) does force the case into UB territory, doesn't it? Michaël Roy m:o) Le 27/03/2021 à 11:35, Jonathan Wakely a écrit : > On Sat, 27 Mar 2021 at 02:26, tika via Libstdc++ wrote: >> >> Synopsys:?? assigning a char to a std::string makes a string 1 char long, >> but what happens if that char is zero??? And showing how easily can this >> UB pass undetected through unit testing... > This is not UB. > >> The story:?? I created a stupid bug, that my unit testing did not >> catch....?? And ended up spending more more time debugging the test than >> fixing my bug. >> >> The bug itself is kind of boring...?? Using the return value of int >> snd_get_name(int, char*) C function from the alsa library, and putting >> an int into a string. That's what I think could be a rather common mistake. >> >> Here's my piece of code, the various tests that could be applied (and >> most fail to detect the bug in my code).?? It turns out that assigning a >> null character to a std::string breaks a lot iof invariants we usually >> depend on.?? All of gcc 10.2.1 (with libstdc++-10.2.1-9), clang 11.0.1 >> and icc 2021.1.2 fail to warn of the mistake with -Wall, for gcc at >> least, that is both both on my system (fedora) and on godbolt.?? MSVC >> does a lot better, with both warnings and different outcome, with str = >> 0 (correctly ?) resulting in an empty string of length zero. > Are you sure you tested the same thing? > >> I know it is UB, > It's not. > > The std::string::operator=(char) overload gets used to assign a single > char to the string, just as though you'd one str.assign("\0", 1). > > but I'm pretty sure the fact that this can go >> undetected so easily by the most common unit testing methods makes it an >> interseting one.?? Is it a feature? Is it something that is part of the >> standard's private UB collection? What does the standard say about >> expected invariants such as s == s.c_str() ? And about the contract of >> std::basic_string::operator(Char) ? > There is no contract. You are allowed to put char(0) into a std::string. > > This is not undefined, and is working as required by the standard. > >> So, here's some code that show the issue and how stcky it is... You can >> also find it here: https://godbolt.org/z/cTWGWohv3 >> >> >> #include >> #include >> #include >> >> // ------------------------------------------------------------------------- >> // simulating what is the C driver FYI, it's the alsa sound driver, >> // but that's not much relevant >> >> char*some_text =nullptr; >> >> voidinit_text() >> { >> ?????? some_text =strdup("some text"); >> } >> >> intget_card_name(int,char** x) >> { >> *x =some_text; >> return0; >> } >> >> // end 'driver' code >> // ------------------------------------------------------------------------- >> >> intmain() >> { >> ?????? init_text(); >> >> ?????? inti =0; >> char*name; >> ?????? std::string s; >> >> // my original bug... &"??! happens. >> ?????? s =get_card_name(i,&name); >> >> // Should have read: >> // if (!get_card_name(i, &name)) >> // s = name; >> >> // simulating EXPECT_FALSE(s.empty()); >> ?????? std::cout <<"s.empty() : "<> >> // simulating EXPECT_NE(s.length(), 0); >> ?????? std::cout <<"s.length() : "<> >> // simulating EXPECT_NE(s, ""); >> ?????? std::cout <<"(s == \"\") : "<<(s =="")<<'\n'; >> >> // simulating EXPECT_EQ(s, s.c_str()); >> ?????? std::cout <<"(s == s.c_str()): "<<(s ==s.c_str())<<" <- bug >> detected!\n"; > This is not a bug. The std::string "\0" is not equal to the const > char* "\0" because the std::string has length 1, but the length of the > const char* is 0. > >> // checking for transmisssion by copy >> ?????? std::string t =s; >> ?????? std::cout <<"t == s : "<<(t ==s)<<" <- transmission of odd >> behaviour by copy\n"; >> >> // a trace to check contents: >> ?????? std::cout <<"s : \""<> >> >> if(!s.empty()) >> ?????? std::cout <<"int(s.front()) : "<<(int)s.front()<<'\n'; >> >> ?????? free(some_text); >> returns.length(); >> } >> >>