Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #79544 > unrolled thread

Why does this work in MSVC 2019...

Started by"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>
First post2021-05-17 16:05 -0700
Last post2021-05-19 20:38 -0700
Articles 20 on this page of 22 — 10 participants

Back to article view | Back to comp.lang.c++


Contents

  Why does this work in MSVC 2019... "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2021-05-17 16:05 -0700
    Re: Why does this work in MSVC 2019... "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2021-05-17 16:11 -0700
      Re: Why does this work in MSVC 2019... Branimir Maksimovic <branimir.maksimovic@gmail.com> - 2021-05-17 23:24 +0000
    Re: Why does this work in MSVC 2019... "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> - 2021-05-18 22:29 +0200
      Re: Why does this work in MSVC 2019... "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2021-05-18 15:09 -0700
        Re: Why does this work in MSVC 2019... Christian Gollwitzer <auriocus@gmx.de> - 2021-05-19 07:57 +0200
          Re: Why does this work in MSVC 2019... James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-05-19 09:58 -0400
    Re: Why does this work in MSVC 2019... Mike Terry <news.dead.person.stones@darjeeling.plus.com> - 2021-05-18 17:01 +0100
      Re: Why does this work in MSVC 2019... Bonita Montero <Bonita.Montero@gmail.com> - 2021-05-18 18:12 +0200
        Re: Why does this work in MSVC 2019... "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2021-05-18 14:50 -0700
          Re: Why does this work in MSVC 2019... Bonita Montero <Bonita.Montero@gmail.com> - 2021-05-19 01:42 +0200
            Re: Why does this work in MSVC 2019... "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2021-05-18 16:48 -0700
              Re: Why does this work in MSVC 2019... Öö Tiib <ootiib@hot.ee> - 2021-05-18 17:55 -0700
                Re: Why does this work in MSVC 2019... "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2021-05-18 20:06 -0700
                  Re: Why does this work in MSVC 2019... Paavo Helde <myfirstname@osa.pri.ee> - 2021-05-19 09:50 +0300
                    Re: Why does this work in MSVC 2019... "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2021-05-19 00:45 -0700
              Re: Why does this work in MSVC 2019... Bonita Montero <Bonita.Montero@gmail.com> - 2021-05-19 07:02 +0200
                Re: Why does this work in MSVC 2019... "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2021-05-19 00:46 -0700
        Re: Why does this work in MSVC 2019... "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2021-05-18 15:10 -0700
      Re: Why does this work in MSVC 2019... "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2021-05-18 14:59 -0700
    Re: Why does this work in MSVC 2019... Andrey Tarasevich <andreytarasevich@hotmail.com> - 2021-05-20 03:44 +0300
      Re: Why does this work in MSVC 2019... "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2021-05-19 20:38 -0700

Page 1 of 2  [1] 2  Next page →


#79544 — Why does this work in MSVC 2019...

From"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>
Date2021-05-17 16:05 -0700
SubjectWhy does this work in MSVC 2019...
Message-ID<s7uss6$12f5$1@gioia.aioe.org>
I don't think this should work at all! It should segfault.
_______________________________
#include <iostream>
#include <algorithm>
#include <string>
#include <set>


struct person
{
     person(std::string const& name, unsigned long id)
     : m_name(name), m_id(id)
     {
         std::cout << "(" << this << ")->person::person(" << name << ", 
" << id << ")\n";
     }

     ~person()
     {
         std::cout << "(" << this << ")->person::~person(" << m_name << 
", " << m_id << ")\n";
     }

     void display() const
     {
         std::cout << "(" << this << ")->person::display(" << m_name << 
", " << m_id << ")\n";
     }

     std::string m_name;
     unsigned long m_id;
};


struct database
{
     struct key_id
     {
         using is_transparent = void; // Humm...

         bool operator() (person const& p0, person const& p1) const
         {
             return p0.m_id < p1.m_id;
         }

         bool operator() (std::string const name, person const& p) const
         {
             return name < p.m_name;
         }

         bool operator() (person const& p, std::string const name) const
         {
             return p.m_name < name;
         }

         bool operator() (unsigned long id, person const& p) const
         {
             return id < p.m_id;
         }

         bool operator() (person const& p, unsigned long id) const
         {
             return p.m_id < id;
         }
     };

     typedef std::set<person, key_id> set_t;

     void add_entry(person const& p0)
     {
         m_set.insert(p0);
     }

     set_t::iterator const& search_id(unsigned long id) const
     {
         return m_set.find(id);
     }

     set_t::iterator const& search_id(std::string const& name) const
     {
         return m_set.find(name);
     }

     void display() const
     {
         std::cout << "\n(" << this << ")->database::display()\n";
         std::cout << "_____________________________________\n";
         std::for_each(m_set.begin(), m_set.end(), [](person const& p)
         {
             p.display();
         });
         std::cout << "_____________________________________\n\n";
     }

     set_t m_set;
};


int main()
{
     {
         database db;

         db.add_entry(person("Chris", 42));
         db.add_entry(person("Lisa", 23));
         db.add_entry(person("Randall", 37));

         std::cout << "_____________________________________\n\n";

         {
             database::set_t::iterator result = db.search_id(37);
             if (result != db.m_set.end())
             {
                 std::cout << "FOUND 37!\n";
                 (*result).display();
             }
         }

         {
             database::set_t::iterator result = db.search_id(137);
             if (result == db.m_set.end()) std::cout << "137 NOT 
FOUND!\n\n";
         }

         {
             database::set_t::iterator result = db.search_id("Lisa");
             if (result != db.m_set.end())
             {
                 std::cout << "FOUND ""Lisa""\n";
                 (*result).display();
             }
         }

         db.display();
     }

     return 0;
}
_______________________________

[toc] | [next] | [standalone]


#79545

From"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>
Date2021-05-17 16:11 -0700
Message-ID<s7ut6u$16ni$1@gioia.aioe.org>
In reply to#79544
On 5/17/2021 4:05 PM, Chris M. Thomasson wrote:
> I don't think this should work at all! It should segfault.
> _______________________________
[snip buggy code that seems to work in MSVC]
> _______________________________
> 

Now, this version should go ahead and work? It seems to.
_________________________________
#include <iostream>
#include <algorithm>
#include <string>
#include <set>


struct person
{
     person(std::string const& name, unsigned long id)
     : m_name(name), m_id(id)
     {
         std::cout << "(" << this << ")->person::person(" << name << ", 
" << id << ")\n";
     }

     ~person()
     {
         std::cout << "(" << this << ")->person::~person(" << m_name << 
", " << m_id << ")\n";
     }

     void display() const
     {
         std::cout << "(" << this << ")->person::display(" << m_name << 
", " << m_id << ")\n";
     }

     std::string m_name;
     unsigned long m_id;
};


struct database
{
     struct key_id
     {
         using is_transparent = void; // Humm...

         bool operator() (person const& p0, person const& p1) const
         {
             return p0.m_id < p1.m_id;
         }

         bool operator() (std::string const name, person const& p) const
         {
             return name < p.m_name;
         }

         bool operator() (person const& p, std::string const name) const
         {
             return p.m_name < name;
         }

         bool operator() (unsigned long id, person const& p) const
         {
             return id < p.m_id;
         }

         bool operator() (person const& p, unsigned long id) const
         {
             return p.m_id < id;
         }
     };

     typedef std::set<person, key_id> set_t;

     void add_entry(person const& p0)
     {
         m_set.insert(p0);
     }

     set_t::iterator const search_id(unsigned long id) const
     {
         return m_set.find(id);
     }

     set_t::iterator const search_id(std::string const& name) const
     {
         return m_set.find(name);
     }

     void display() const
     {
         std::cout << "\n(" << this << ")->database::display()\n";
         std::cout << "_____________________________________\n";
         std::for_each(m_set.begin(), m_set.end(), [](person const& p)
         {
             p.display();
         });
         std::cout << "_____________________________________\n\n";
     }

     set_t m_set;
};


int main()
{
     {
         database db;

         db.add_entry(person("Chris", 42));
         db.add_entry(person("Lisa", 23));
         db.add_entry(person("Randall", 37));

         std::cout << "_____________________________________\n\n";

         {
             database::set_t::iterator const& result = db.search_id(37);
             if (result != db.m_set.end())
             {
                 std::cout << "FOUND 37!\n";
                 (*result).display();
             }
         }

         {
             database::set_t::iterator const& result = db.search_id(137);
             if (result == db.m_set.end()) std::cout << "137 NOT 
FOUND!\n\n";
         }

         {
             database::set_t::iterator const& result = db.search_id("Lisa");
             if (result != db.m_set.end())
             {
                 std::cout << "FOUND ""Lisa""\n";
                 (*result).display();
             }
         }

         db.display();
     }

     return 0;
}
_________________________________

[toc] | [prev] | [next] | [standalone]


#79546

FromBranimir Maksimovic <branimir.maksimovic@gmail.com>
Date2021-05-17 23:24 +0000
Message-ID<mWCoI.547458$nn2.394399@fx48.iad>
In reply to#79545
On 2021-05-17, Chris M. Thomasson <chris.m.thomasson.1@gmail.com> wrote:
> On 5/17/2021 4:05 PM, Chris M. Thomasson wrote:
>> I don't think this should work at all! It should segfault.
>> _______________________________
> [snip buggy code that seems to work in MSVC]
>> _______________________________
>> 
>
> Now, this version should go ahead and work? It seems to.

Correcti, first version segfaults because temporary and I have warning,
second version does not has warning and works.


-- 
current job title: senior software engineer
skills: x86 aasembler,c++,c,rust,go,nim,haskell...

press any key to continue or any other to quit...

[toc] | [prev] | [next] | [standalone]


#79559

From"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>
Date2021-05-18 22:29 +0200
Message-ID<s8182f$r9c$1@dont-email.me>
In reply to#79544
On 18.05.2021 01:05, Chris M. Thomasson wrote:
> I don't think this should work at all! It should segfault.
> 
>      set_t::iterator const& search_id(unsigned long id) const

Well UB is UB. That includes that things may appear to work.

- ALf

[toc] | [prev] | [next] | [standalone]


#79569

From"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>
Date2021-05-18 15:09 -0700
Message-ID<s81dul$1j9v$2@gioia.aioe.org>
In reply to#79559
On 5/18/2021 1:29 PM, Alf P. Steinbach wrote:
> On 18.05.2021 01:05, Chris M. Thomasson wrote:
>> I don't think this should work at all! It should segfault.
>>
>>      set_t::iterator const& search_id(unsigned long id) const
> 
> Well UB is UB. That includes that things may appear to work.

Indeed. Mike Terry mentioned something about a stack issue.

[toc] | [prev] | [next] | [standalone]


#79589

FromChristian Gollwitzer <auriocus@gmx.de>
Date2021-05-19 07:57 +0200
Message-ID<s829br$dld$1@dont-email.me>
In reply to#79569
Am 19.05.21 um 00:09 schrieb Chris M. Thomasson:
> On 5/18/2021 1:29 PM, Alf P. Steinbach wrote:
>> On 18.05.2021 01:05, Chris M. Thomasson wrote:
>>> I don't think this should work at all! It should segfault.
>>>
>>>      set_t::iterator const& search_id(unsigned long id) const
>>
>> Well UB is UB. That includes that things may appear to work.
> 
> Indeed. Mike Terry mentioned something about a stack issue.
> 

You are basically accessing memory that was "freed"[*] before. That is 
totally undefined, of course, but there is no guarantee that it 
segfaults. The CPU can not check every small allocation on the stack or 
heap for correctness. Instead, the memory is structured into pages of 
typically 4kB in size. The CPU only checks that the page was allocated 
for the current process, so as long as there is any other valid object 
in this page, there is no segfault. This also explains why programs with 
memory errors often crash in a totally different location. If a pointer 
gets mangled, then it segfaults at the point where the pointer is used 
and suddenly points into the woods.

You can use a memory debugger to detect these problems, like valgrind on 
Linux (one of the best) or the flag -fsanitize=address with clang. Then, 
every object is allocated on its own page, making the program very 
bloated and slow, but the program will then segfault immediately at the 
point where the deleted object is accessed.


[*] not on the heap, so not "malloc/free-type freed", but "stack-freed"

Best regards,

	Christian

[toc] | [prev] | [next] | [standalone]


#79627

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2021-05-19 09:58 -0400
Message-ID<s835ij$b43$1@dont-email.me>
In reply to#79589
On 5/19/21 1:57 AM, Christian Gollwitzer wrote:
...
> You are basically accessing memory that was "freed"[*] before. That is 
...
> [*] not on the heap, so not "malloc/free-type freed", but "stack-freed"

I have not bothered checking his code to verify that your diagnosis is
correct. However, if it is, the correct way to describe your diagnosis
is to say that his code attempts to access the value stored in an object
after the lifetime of that object has ended. That description covers
both dynamically allocated objects that have been deallocated, and
automatic objects after the block in which they are defined exits.

[toc] | [prev] | [next] | [standalone]


#79563

FromMike Terry <news.dead.person.stones@darjeeling.plus.com>
Date2021-05-18 17:01 +0100
Message-ID<ZMWdnfgfS_tueT79nZ2dnUU78RfNnZ2d@brightview.co.uk>
In reply to#79544
On 18/05/2021 00:05, Chris M. Thomasson wrote:
> I don't think this should work at all! It should segfault.
> _______________________________
> #include <iostream>
> #include <algorithm>
> #include <string>
> #include <set>
> 
> 
> struct person
> {
>      person(std::string const& name, unsigned long id)
>      : m_name(name), m_id(id)
>      {
>          std::cout << "(" << this << ")->person::person(" << name << ", 
> " << id << ")\n";
>      }
> 
>      ~person()
>      {
>          std::cout << "(" << this << ")->person::~person(" << m_name << 
> ", " << m_id << ")\n";
>      }
> 
>      void display() const
>      {
>          std::cout << "(" << this << ")->person::display(" << m_name << 
> ", " << m_id << ")\n";
>      }
> 
>      std::string m_name;
>      unsigned long m_id;
> };
> 
> 
> struct database
> {
>      struct key_id
>      {
>          using is_transparent = void; // Humm...
> 
>          bool operator() (person const& p0, person const& p1) const
>          {
>              return p0.m_id < p1.m_id;
>          }
> 
>          bool operator() (std::string const name, person const& p) const
>          {
>              return name < p.m_name;
>          }
> 
>          bool operator() (person const& p, std::string const name) const
>          {
>              return p.m_name < name;
>          }
> 
>          bool operator() (unsigned long id, person const& p) const
>          {
>              return id < p.m_id;
>          }
> 
>          bool operator() (person const& p, unsigned long id) const
>          {
>              return p.m_id < id;
>          }
>      };
> 
>      typedef std::set<person, key_id> set_t;
> 
>      void add_entry(person const& p0)
>      {
>          m_set.insert(p0);
>      }
> 
>      set_t::iterator const& search_id(unsigned long id) const
>      {
>          return m_set.find(id);
>      }
> 
>      set_t::iterator const& search_id(std::string const& name) const
>      {
>          return m_set.find(name);
>      }
> 
>      void display() const
>      {
>          std::cout << "\n(" << this << ")->database::display()\n";
>          std::cout << "_____________________________________\n";
>          std::for_each(m_set.begin(), m_set.end(), [](person const& p)
>          {
>              p.display();
>          });
>          std::cout << "_____________________________________\n\n";
>      }
> 
>      set_t m_set;
> };
> 
> 
> int main()
> {
>      {
>          database db;
> 
>          db.add_entry(person("Chris", 42));
>          db.add_entry(person("Lisa", 23));
>          db.add_entry(person("Randall", 37));
> 
>          std::cout << "_____________________________________\n\n";
> 
>          {
>              database::set_t::iterator result = db.search_id(37);
>              if (result != db.m_set.end())
>              {
>                  std::cout << "FOUND 37!\n";
>                  (*result).display();
>              }
>          }
> 
>          {
>              database::set_t::iterator result = db.search_id(137);
>              if (result == db.m_set.end()) std::cout << "137 NOT 
> FOUND!\n\n";
>          }
> 
>          {
>              database::set_t::iterator result = db.search_id("Lisa");
>              if (result != db.m_set.end())
>              {
>                  std::cout << "FOUND ""Lisa""\n";
>                  (*result).display();
>              }
>          }
> 
>          db.display();
>      }
> 
>      return 0;
> }
> _______________________________

Posting around 150 lines of code, then asking "why doesn't this 
segfault?" with no further explanation isn't good.  It would have been 
helpful at least have said which bit of code you thought should produce 
a segfault...

OK, so I guess your issue is with the two search_id functions, which 
return a reference to a local result, e.g.:

 >      set_t::iterator const& search_id(unsigned long id) const
 >      {
 >          return m_set.find(id);
 >      }

When these are used you expect a segfault, but when I run the code (MSVS 
17) there is no seg-fault because the original iterator storage on the 
stack hasn't been overwritten at that point.  (There is a compile 
warning "returning address of local variable or temporary".)

The obvious correct approach would be to just return the iterator by 
value.  (And I'd wonder why would you want to make it const, but I 
suppose this is some kind of experiment rather than production code.)


Mike.

[toc] | [prev] | [next] | [standalone]


#79564

FromBonita Montero <Bonita.Montero@gmail.com>
Date2021-05-18 18:12 +0200
Message-ID<s80p1o$a0i$1@dont-email.me>
In reply to#79563
>  >      set_t::iterator const& search_id(unsigned long id) const
>  >      {
>  >          return m_set.find(id);
>  >      }

Totally brain-damaged.

[toc] | [prev] | [next] | [standalone]


#79566

From"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>
Date2021-05-18 14:50 -0700
Message-ID<s81cr4$15eb$1@gioia.aioe.org>
In reply to#79564
On 5/18/2021 9:12 AM, Bonita Montero wrote:
>>  >      set_t::iterator const& search_id(unsigned long id) const
>>  >      {
>>  >          return m_set.find(id);
>>  >      }
> 
> Totally brain-damaged.

:^)

I was just wondering why MSVC allows this to run in the first place.

[toc] | [prev] | [next] | [standalone]


#79572

FromBonita Montero <Bonita.Montero@gmail.com>
Date2021-05-19 01:42 +0200
Message-ID<s81jdl$272$1@dont-email.me>
In reply to#79566
>>>  >      set_t::iterator const& search_id(unsigned long id) const
>>>  >      {
>>>  >          return m_set.find(id);
>>>  >      }
>>
>> Totally brain-damaged.

> :^)
> I was just wondering why MSVC allows this to run in the first place.

Why not ? It's not uncompilable code.

[toc] | [prev] | [next] | [standalone]


#79573

From"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>
Date2021-05-18 16:48 -0700
Message-ID<s81jp6$1kfb$1@gioia.aioe.org>
In reply to#79572
On 5/18/2021 4:42 PM, Bonita Montero wrote:
>>>>  >      set_t::iterator const& search_id(unsigned long id) const
>>>>  >      {
>>>>  >          return m_set.find(id);
>>>>  >      }
>>>
>>> Totally brain-damaged.
> 
>> :^)
>> I was just wondering why MSVC allows this to run in the first place.
> 
> Why not ? It's not uncompilable code.

Well, warnings aside for a moment, it seems to compile, _and_ run on 
MSVC, however it will not even run on GCC without a segfault. Plus, the 
code has a bug. I get warnings in MSVC, but it still runs it to 
completion. I was just wondering why.

[toc] | [prev] | [next] | [standalone]


#79579

FromÖö Tiib <ootiib@hot.ee>
Date2021-05-18 17:55 -0700
Message-ID<f7503b30-9b74-4c22-a265-71db5e620f42n@googlegroups.com>
In reply to#79573
On Wednesday, 19 May 2021 at 02:49:13 UTC+3, Chris M. Thomasson wrote:
> On 5/18/2021 4:42 PM, Bonita Montero wrote: 
> >>>> > set_t::iterator const& search_id(unsigned long id) const 
> >>>> > { 
> >>>> > return m_set.find(id); 
> >>>> > } 
> >>> 
> >>> Totally brain-damaged. 
> > 
> >> :^) 
> >> I was just wondering why MSVC allows this to run in the first place. 
> > 
> > Why not ? It's not uncompilable code.
> Well, warnings aside for a moment, it seems to compile, _and_ run on 
> MSVC, however it will not even run on GCC without a segfault. Plus, the 
> code has a bug. I get warnings in MSVC, but it still runs it to 
> completion. I was just wondering why.

The segfault indicates that  gcc allows it to run as well unless you mean
that the compiler segfaults (that i've not seen gcc to do for ages). 

MSVC did allow to take lvalue references to non const of temporaries (that
should not compile) for quite long time. I have not checked if it has
stopped it finally ... that may have something to do with different outcome
of undefined behavior.

Undefined behavior is what it is ... different nasal demons or lack
of such from repeated runs of same compiled binary with same
data are rare but possible with MSVC and gcc alike.

[toc] | [prev] | [next] | [standalone]


#79582

From"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>
Date2021-05-18 20:06 -0700
Message-ID<s81vc4$16fq$1@gioia.aioe.org>
In reply to#79579
On 5/18/2021 5:55 PM, Öö Tiib wrote:
> On Wednesday, 19 May 2021 at 02:49:13 UTC+3, Chris M. Thomasson wrote:
>> On 5/18/2021 4:42 PM, Bonita Montero wrote:
>>>>>>> set_t::iterator const& search_id(unsigned long id) const
>>>>>>> {
>>>>>>> return m_set.find(id);
>>>>>>> }
>>>>>
>>>>> Totally brain-damaged.
>>>
>>>> :^)
>>>> I was just wondering why MSVC allows this to run in the first place.
>>>
>>> Why not ? It's not uncompilable code.
>> Well, warnings aside for a moment, it seems to compile, _and_ run on
>> MSVC, however it will not even run on GCC without a segfault. Plus, the
>> code has a bug. I get warnings in MSVC, but it still runs it to
>> completion. I was just wondering why.
> 
> The segfault indicates that  gcc allows it to run as well unless you mean
> that the compiler segfaults (that i've not seen gcc to do for ages).

Yes, GCC allows it to run with warnings, and segfaults, and does not 
allow the bugged program to run to completion.


> 
> MSVC did allow to take lvalue references to non const of temporaries (that
> should not compile) for quite long time. I have not checked if it has
> stopped it finally ... that may have something to do with different outcome
> of undefined behavior.

MSVC allows that now. It compiles the bugged code, spits out a couple of 
warnings, and lets the compiled program run to completion. Strange.


> 
> Undefined behavior is what it is ... different nasal demons or lack
> of such from repeated runs of same compiled binary with same
> data are rare but possible with MSVC and gcc alike.
> 

Big time.

[toc] | [prev] | [next] | [standalone]


#79590

FromPaavo Helde <myfirstname@osa.pri.ee>
Date2021-05-19 09:50 +0300
Message-ID<s82ceq$u3c$1@dont-email.me>
In reply to#79582
19.05.2021 06:06 Chris M. Thomasson kirjutas:
> On 5/18/2021 5:55 PM, Öö Tiib wrote:
>> The segfault indicates that  gcc allows it to run as well unless you mean
>> that the compiler segfaults (that i've not seen gcc to do for ages).
> 
> Yes, GCC allows it to run with warnings, and segfaults, and does not 
> allow the bugged program to run to completion.

It's not GCC, but the hardware+OS which kills the running program. You 
can compile the program with GCC for a platform without memory 
protection (like 8086) and it will never segfault (because there are 
neither segments nor faults). It might do other funny things though.

> MSVC allows that now. It compiles the bugged code, spits out a couple of 
> warnings, and lets the compiled program run to completion. Strange.

This is normal for undefined behavior. Anything would be normal.

OTOH, it's not normal for a programmer to ignore compiler warnings about 
returning references to temporaries. You might want to use the "Treat 
Specific Errors as Warnings" compiler feature for this warning 
(/we"4172" with MSVC).

The only reason this is a warning and not an error is because UB 
formally only appears when dereferencing the invalid pointer/reference, 
returning it from a function is actually fine.

[toc] | [prev] | [next] | [standalone]


#79596

From"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>
Date2021-05-19 00:45 -0700
Message-ID<s82fm0$11c1$1@gioia.aioe.org>
In reply to#79590
On 5/18/2021 11:50 PM, Paavo Helde wrote:
> 19.05.2021 06:06 Chris M. Thomasson kirjutas:
>> On 5/18/2021 5:55 PM, Öö Tiib wrote:
>>> The segfault indicates that  gcc allows it to run as well unless you 
>>> mean
>>> that the compiler segfaults (that i've not seen gcc to do for ages).
>>
>> Yes, GCC allows it to run with warnings, and segfaults, and does not 
>> allow the bugged program to run to completion.
> 
> It's not GCC, but the hardware+OS which kills the running program. You 
> can compile the program with GCC for a platform without memory 
> protection (like 8086) and it will never segfault (because there are 
> neither segments nor faults). It might do other funny things though.
> 
>> MSVC allows that now. It compiles the bugged code, spits out a couple 
>> of warnings, and lets the compiled program run to completion. Strange.
> 
> This is normal for undefined behavior. Anything would be normal.
> 
> OTOH, it's not normal for a programmer to ignore compiler warnings about 
> returning references to temporaries. You might want to use the "Treat 
> Specific Errors as Warnings" compiler feature for this warning 
> (/we"4172" with MSVC).
> 
> The only reason this is a warning and not an error is because UB 
> formally only appears when dereferencing the invalid pointer/reference, 
> returning it from a function is actually fine.

100% agreed! I saw the warnings, but was interested into why the program 
was allowed to run to completion under MSVC. Then I tried it GCC, 
different things occurred. Its the nature of the beast wrt UB. I thank 
you and everybody else for their time and patience.

[toc] | [prev] | [next] | [standalone]


#79588

FromBonita Montero <Bonita.Montero@gmail.com>
Date2021-05-19 07:02 +0200
Message-ID<s8264p$rul$1@dont-email.me>
In reply to#79573
> Well, warnings aside for a moment, it seems to compile, _and_ run
> on  MSVC, however it will not even run on GCC without a segfault.

It's implementation-defined how long the memory of the temporary is
untouched.

[toc] | [prev] | [next] | [standalone]


#79597

From"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>
Date2021-05-19 00:46 -0700
Message-ID<s82fot$11c1$2@gioia.aioe.org>
In reply to#79588
On 5/18/2021 10:02 PM, Bonita Montero wrote:
>> Well, warnings aside for a moment, it seems to compile, _and_ run
>> on  MSVC, however it will not even run on GCC without a segfault.
> 
> It's implementation-defined how long the memory of the temporary is
> untouched.

This is pretty much exactly what is occurring. Thanks Bonita, and thanks 
again for the heads up on is_transparent!

[toc] | [prev] | [next] | [standalone]


#79570

From"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>
Date2021-05-18 15:10 -0700
Message-ID<s81e0p$1j9v$3@gioia.aioe.org>
In reply to#79564
On 5/18/2021 9:12 AM, Bonita Montero wrote:
>>  >      set_t::iterator const& search_id(unsigned long id) const
>>  >      {
>>  >          return m_set.find(id);
>>  >      }
> 
> Totally brain-damaged.

Yeah. It is. Sorry!

[toc] | [prev] | [next] | [standalone]


#79567

From"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>
Date2021-05-18 14:59 -0700
Message-ID<s81dc0$1b1r$1@gioia.aioe.org>
In reply to#79563
On 5/18/2021 9:01 AM, Mike Terry wrote:
> On 18/05/2021 00:05, Chris M. Thomasson wrote:
>> I don't think this should work at all! It should segfault.
>> _______________________________
[...]
>> _______________________________
> 
> Posting around 150 lines of code, then asking "why doesn't this 
> segfault?" with no further explanation isn't good.  It would have been 
> helpful at least have said which bit of code you thought should produce 
> a segfault...

Yeah, sorry about that.


> OK, so I guess your issue is with the two search_id functions, which 
> return a reference to a local result, e.g.:
> 
>  >      set_t::iterator const& search_id(unsigned long id) const
>  >      {
>  >          return m_set.find(id);
>  >      }
> 
> When these are used you expect a segfault, but when I run the code (MSVS 
> 17) there is no seg-fault because the original iterator storage on the 
> stack hasn't been overwritten at that point.  (There is a compile 
> warning "returning address of local variable or temporary".)
> 
> The obvious correct approach would be to just return the iterator by 
> value.  (And I'd wonder why would you want to make it const, but I 
> suppose this is some kind of experiment rather than production code.)

It is a crude quick experiment. I never used is_transparent before. Then 
I noticed that MSVC actually runs the bugged code. I got the warnings as 
well, but still wondered about why it ran to completion.

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | comp.lang.c++


csiph-web