Quantcast

Compare boost::system::error_category

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
21 messages Options
12
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Compare boost::system::error_category

Christopher Pisz
The following comparison fails for an error whom outputs "asio.misc" for errorCode.category().name() and "end of file" for errorCode.message()

If it claims to be in category asio.misc, then why does the if condition of (errorCode.category() == boost::asio::error::misc_category ) evaluate to false?

Googling says that a boost::system::error_code can have the same value in more than one category, so I assume that in order to get the proper message and meaning we must compare boost::system::error_category as well as boost::system::error_code::value.

How do we properly compare the category if this fails to work?

Code in question:
//--------------------------------------------------------------------------------------------------
std::string ClientSocketASIO::ErrorCodeToString(const boost::system::error_code & errorCode)
{
    std::ostringstream debugMsg;
    debugMsg << " Error Category: " << errorCode.category().name() << ". "
             << " Error Message: "  << errorCode.message() << ". ";

    if( errorCode.category() == boost::asio::error::misc_category )
    {
        switch (errorCode.value())
        {
        case boost::asio::error::eof:
            debugMsg << ". Server has disconnected.";
            break;
        case boost::asio::error::connection_refused:
            debugMsg << ". Connection Refused";
            break;
        default:
            debugMsg << ". Unknown Error.";
            break;
        }
    }
    else
    {
        debugMsg << ". Unknown Error category.";
    }

    return debugMsg.str();
}
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Compare boost::system::error_category

Boost - Users mailing list
On 24/03/2017 09:26, Christopher Pisz wrote:

> The following comparison fails for an error whom outputs "asio.misc" for
> errorCode.category().name() and "end of file" for errorCode.message()
>
> If it claims to be in category asio.misc, then why does the if condition of
> (errorCode.category() == boost::asio::error::misc_category ) evaluate to
> false?
>
> Googling says that a boost::system::error_code can have the same value in
> more than one category, so I assume that in order to get the proper message
> and meaning we must compare boost::system::error_category as well as
> boost::system::error_code::value.
>
> How do we properly compare the category if this fails to work?

If they appear to have equal value but aren't equal, you might have a
problem with multiple definitions.  The most common problem is where
you're using some shared libraries (DLL or SO) and trying to pass errors
across the boundary.  This works as expected only when you ensure that
the dependencies of both sides also use the Boost libraries (esp. ASIO
and System) as shared libraries, not as static libraries.

When you're linking your Boost-using application with Boost-using shared
libraries (and when the Boost types are used in the API between them),
it's generally best to ensure that the shared libraries are used.  On
Linux, this generally just happens (as long as the shared libraries have
been compiled and are in the same or earlier library path as the static
libraries), but on Windows you should also define BOOST_ALL_DYN_LINK on
both sides.


_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Compare boost::system::error_category

Christopher Pisz
Sounds like that could solve my problem. However, I am using the Nuget boost package and it seem to set up linking automatically? I don't see anything in the project settings for include directories or additional library directories. When I define BOOST_ALL_DYN_LINK the process runs without the dll being copied to the output directory, so I suspect it is ignoring it.

So, might be OT here, but going to have to track down some insight on how to dynamically link boost with the Nuget package.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Compare boost::system::error_category

Christopher Pisz

(MSVS Specific)

So I've edited all the target files for the public Nuget packages for all the boost libraries I am using to look like:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemDefinitionGroup Condition="'$(Platform)'=='Win32'">
        <ClCompile>
      <PreprocessorDefinitions>BOOST_ALL_DYN_LINK;%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </ClCompile>
    <Link>
      <AdditionalLibraryDirectories>$(MSBuildThisFileDirectory)..\..\lib\native\address-model-32\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
    </Link>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Platform)'=='x64'">
        <ClCompile>
      <PreprocessorDefinitions>BOOST_ALL_DYN_LINK;%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </ClCompile>
    <Link>
      <AdditionalLibraryDirectories>$(MSBuildThisFileDirectory)..\..\lib\native\address-model-64\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
    </Link>
  </ItemDefinitionGroup>
  <ItemGroup />
 
  <Target Name="CopyBoostAtomicDll" BeforeTargets="PrepareForBuild">
          <Copy SourceFiles="$(MSBuildThisFileDirectory)..\..\lib\native\address-model-32\lib\boost_atomic-vc100-mt-1_62.dll"
                  DestinationFolder="$(OutDir)" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
          <Copy SourceFiles="$(MSBuildThisFileDirectory)..\..\lib\native\address-model-32\lib\boost_atomic-vc100-mt-gd-1_62.dll"
                  DestinationFolder="$(OutDir)" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
  </Target>
 
</Project>


(General)

So, now I am dynamically linking to all boost libraries and if I use the following code, I get the expected results. If I statically link, all the if conditions evaluate to false. This seems like a very big problem to me and very unexpected.

//--------------------------------------------------------------------------------------------------
std::string ClientSocketASIO::ErrorCodeToString(const boost::system::error_code & errorCode)
{
    std::ostringstream debugMsg;
    debugMsg << " Error Category: " << errorCode.category().name() << ". "
             << " Error Message: "  << errorCode.message() << ". ";

    // IMPORTANT - These comparisons only work if you dynamically link boost libraries
    //             Because boost chose to implement boost::system::error_category::operator == by comparing addresses
    //             The addresses are different in one library and the other when statically linking.
    //
    // We use make_error_code macro to make the correct category as well as error code value.
    // Error code value is not unique and can be duplicated in more than one category.
    if (errorCode == make_error_code(boost::asio::error::connection_refused))
    {
        debugMsg << ". Connection Refused";
    }
    else if (errorCode == make_error_code(boost::asio::error::eof))
    {
        debugMsg << ". Server has disconnected.";
    }
    else
    {
        debugMsg << ". boost::system::error_code has not been mapped to a meaningful message.";
    }

    return debugMsg.str();
}

Why would the authors use address comparison for the boost::system::error_category and leave us getting different results if we statically link vs dynamically link?

Also, is my error_code comparison now the proper and correct way to compare error codes?
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Compare boost::system::error_category

Boost - Users mailing list
In reply to this post by Christopher Pisz
On 23/03/2017 20:26, Christopher Pisz via Boost-users wrote:
> The following comparison fails for an error whom outputs "asio.misc" for
> errorCode.category().name() and "end of file" for errorCode.message()

The C++ 11 standard implies that each error category instance shall have
a globally unique address and comparisons of equality shall use that
address to compare. Unfortunately, this is not reliable in portable
code, only the Dinkumware STL implements true address uniqueness
anywhere in the process and it adds a full memory barrier to achieve
that i.e. it's expensive.

Boost's quality of implementation is the same as libstdc++ or libc++,
you can get multiple instantiations in certain circumstances and those
can have differing addresses.

In my own code, I do the comparison operator first, and if that fails I
do a strcmp() of the category's name(). To date, this has not bitten me.
I would personally consider this aspect of error categories to be a
defect in the standard, as specified it forces non-header-only
implementation if you want it to be conforming, and even that doesn't
cover RTLD_LOCAL which means you need to fall back onto named shared
memory or some hack.

Niall

--
ned Productions Limited Consulting
http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Compare boost::system::error_category

Boost - Users mailing list
In reply to this post by Christopher Pisz
On 03/25/2017 12:32 AM, Niall Douglas via Boost-users wrote:

> Boost's quality of implementation is the same as libstdc++ or libc++,
> you can get multiple instantiations in certain circumstances and those
> can have differing addresses.

The various error categories are implemented (for header-only libraries)
as inlined Meyer singletons. Does that mean that we have a general
problem with such singletons?

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Compare boost::system::error_category

Boost - Users mailing list
On 3/25/17 7:12 AM, Bjorn Reese via Boost-users wrote:

> On 03/25/2017 12:32 AM, Niall Douglas via Boost-users wrote:
>
>> Boost's quality of implementation is the same as libstdc++ or libc++,
>> you can get multiple instantiations in certain circumstances and those
>> can have differing addresses.
>
> The various error categories are implemented (for header-only libraries)
> as inlined Meyer singletons. Does that mean that we have a general
> problem with such singletons?
>
I think the issue is that for C++ versions prior to C++11, it isn't
guaranteed to be thread safe, as C++ had no concept of threads (which
sort of makes anything you do with threads problematical). With C++11,
if fully implemented, it should be thread safe as the standard now
requires the compiler to implement the required thread safety, the issue
is that there may be implementation that don't fully provide that as it
can be a bit expensive in some cases.


--
Richard Damon

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Compare boost::system::error_category

Boost - Users mailing list
I have run into boost issues even when dynamically linking everything.


It's actually quite concerning.

James

On Saturday, March 25, 2017, Richard Damon via Boost-users <[hidden email]> wrote:
On 3/25/17 7:12 AM, Bjorn Reese via Boost-users wrote:
On 03/25/2017 12:32 AM, Niall Douglas via Boost-users wrote:

Boost's quality of implementation is the same as libstdc++ or libc++,
you can get multiple instantiations in certain circumstances and those
can have differing addresses.

The various error categories are implemented (for header-only libraries)
as inlined Meyer singletons. Does that mean that we have a general
problem with such singletons?

I think the issue is that for C++ versions prior to C++11, it isn't guaranteed to be thread safe, as C++ had no concept of threads (which sort of makes anything you do with threads problematical). With C++11, if fully implemented, it should be thread safe as the standard now requires the compiler to implement the required thread safety, the issue is that there may be implementation that don't fully provide that as it can be a bit expensive in some cases.


--
Richard Damon

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Compare boost::system::error_category

Boost - Users mailing list
In reply to this post by Boost - Users mailing list
>> Boost's quality of implementation is the same as libstdc++ or libc++,
>> you can get multiple instantiations in certain circumstances and those
>> can have differing addresses.
>
> The various error categories are implemented (for header-only libraries)
> as inlined Meyer singletons. Does that mean that we have a general
> problem with such singletons?

The short answer is yes, the error category comparison operators are
unreliable on all major STLs apart from Dinkumware's and in Boost.

The longer answer is that the hack of strcmp()ing the name() works
surprisingly well in practice, and it might be wise if Boost's error
categories implemented that, followed by libstdc++ and libc++.

I expect after Charley Bay bangs the drum on this stuff at C++ Now
followed very shortly thereafter by me banging the drum at ACCU that we
might draw some attention to this problem by the STL maintainers. The
only one who really gets the problem is Stephan, but his solution for
Dinkumware does bring in an atomic fence which he himself admits is a
bit heavy. It certainly causes a lot of code bloat when using Outcome
with the Dinkumware STL, as every possible error code construction point
requires an atomic fence.

I've done some remedial evil hackery in Outcome to bypass Stephan's
atomic fence some of the time on VS. It's the best I can do given the
constraints.

Niall

--
ned Productions Limited Consulting
http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Compare boost::system::error_category

Boost - Users mailing list
In reply to this post by Boost - Users mailing list
On 25/03/2017 12:01, Richard Damon via Boost-users wrote:

>>> Boost's quality of implementation is the same as libstdc++ or libc++,
>>> you can get multiple instantiations in certain circumstances and those
>>> can have differing addresses.
>>
>> The various error categories are implemented (for header-only libraries)
>> as inlined Meyer singletons. Does that mean that we have a general
>> problem with such singletons?
>>
> I think the issue is that for C++ versions prior to C++11, it isn't
> guaranteed to be thread safe, as C++ had no concept of threads (which
> sort of makes anything you do with threads problematical). With C++11,
> if fully implemented, it should be thread safe as the standard now
> requires the compiler to implement the required thread safety, the issue
> is that there may be implementation that don't fully provide that as it
> can be a bit expensive in some cases.

I know of no linker based method to bypass multiple category instances
occurring in ELF if a library is loaded via RTLD_LOCAL. You need to fall
back onto named memory maps in that situation.

Niall

--
ned Productions Limited Consulting
http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Compare boost::system::error_category

Boost - Users mailing list
In reply to this post by Boost - Users mailing list
On 25/03/2017 12:44, james via Boost-users wrote:
> I have run into boost issues even when dynamically linking everything.
>
> http://stackoverflow.com/questions/39948997/use-of-boost-log-and-boost-asio-causes-a-crash/39958285#39958285
>
> It's actually quite concerning.

There are very long standing ABI issues with Boost, but before C++ 11 it
was hard to do something about it which wasn't disruptive to end users.

I've proposed the scheme described at
https://ned14.github.io/boost.outcome/md_doc_md_07-faq.html, but it has
not gained traction with the Boost community.

Niall

--
ned Productions Limited Consulting
http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Compare boost::system::error_category

Boost - Users mailing list
In reply to this post by Boost - Users mailing list
On 03/25/2017 01:45 PM, Niall Douglas via Boost-users wrote:

>>> Boost's quality of implementation is the same as libstdc++ or libc++,
>>> you can get multiple instantiations in certain circumstances and those
>>> can have differing addresses.
>>
>> The various error categories are implemented (for header-only libraries)
>> as inlined Meyer singletons. Does that mean that we have a general
>> problem with such singletons?
>
> The short answer is yes, the error category comparison operators are
> unreliable on all major STLs apart from Dinkumware's and in Boost.

Can you elaborate on what the core problem is?

You have mentioned both memory barriers and RTLD_LOCAL which seem to
imply different problems (concurrency versus relocation of weak
symbols.)

Please notice that I am interested in singletons in general, not only
error categories.

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Compare boost::system::error_category

Boost - Users mailing list
>>>> Boost's quality of implementation is the same as libstdc++ or libc++,
>>>> you can get multiple instantiations in certain circumstances and those
>>>> can have differing addresses.
>>>
>>> The various error categories are implemented (for header-only libraries)
>>> as inlined Meyer singletons. Does that mean that we have a general
>>> problem with such singletons?
>>
>> The short answer is yes, the error category comparison operators are
>> unreliable on all major STLs apart from Dinkumware's and in Boost.
>
> Can you elaborate on what the core problem is?

To generate ELF object A using header only library X which defines a
custom error category, the linker chooses any one of the implementations
of that error category in the object files linked as it is marked weak
due to being inline. Due to use of -fvisibility=hidden, symbol for
custom error category is not exported.

To generate ELF object B using header only library X which defines a
custom error category, the linker chooses any one of the implementations
of that error category in the object files linked as it is marked weak
due to being inline. Due to use of -fvisibility=hidden, symbol for
custom error category is not exported.

Program C links against ELF object A and ELF object B. There are now two
instances of the same category object, and their addresses will not
equal. Possible solution: Mark custom error category retrieval function
with default visibility?

That will work with RTLD_GLOBAL. But what if a SO is loaded with
RTLD_LOCAL? That establishes multiple global symbol tables, and once
again two instances of the same error category appear.

The exact same problem applies to the RTTI used to catch exception
throws. The problem was fixed on libstdc++ by using string comparison to
compare RTTI if address comparison failed. libc++ used to noisily take a
stand against string comparison and insist on address comparison, but
they may since have buckled under the constant bugs about exceptions not
being caught.

> You have mentioned both memory barriers and RTLD_LOCAL which seem to
> imply different problems (concurrency versus relocation of weak
> symbols.)

MSVC has the advantage of controlling its ABI. They invented a thing
called _Immortalize which gets specially treated by the linker to
instantiate exactly one of the thing ever in a process. As the VS2015
source file says, /* MAGIC */. Because multiple threads could reach the
instantiation concurrently, it needs to be a memory barrier so one gets
chosen and the others wait.

> Please notice that I am interested in singletons in general, not only
> error categories.

PE and MachO are the least affected by this problem because their
creators thought of symbol encapsulation in advance. ELF is severely
affected by it. The fault is in the ELF spec which assumes a globally
visible unique symbol table. I have tried raising this problem with
those responsible for ELF on a number of occasions in the past, it was
considered not a problem for the linker and ELF folk, they felt it was a
C++ problem. Attempting to explain this was not a problem in PE nor
MachO nor many other binary formats got me nowhere.

Niall

--
ned Productions Limited Consulting
http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Compare boost::system::error_category

Christopher Pisz
What would be so wrong with category being an actual number to compare against?

I don't know anyone whom creates classes and operator == using the address of that class. You guys talk about the standard and what not, and admittedly I've never looked inside how they implement things, but I've never had such problems using the STL either.

On Sat, Mar 25, 2017 at 5:58 PM, Boost - Users mailing list [via Boost] <[hidden email]> wrote:
>>>> Boost's quality of implementation is the same as libstdc++ or libc++,

>>>> you can get multiple instantiations in certain circumstances and those
>>>> can have differing addresses.
>>>
>>> The various error categories are implemented (for header-only libraries)
>>> as inlined Meyer singletons. Does that mean that we have a general
>>> problem with such singletons?
>>
>> The short answer is yes, the error category comparison operators are
>> unreliable on all major STLs apart from Dinkumware's and in Boost.
>
> Can you elaborate on what the core problem is?
To generate ELF object A using header only library X which defines a
custom error category, the linker chooses any one of the implementations
of that error category in the object files linked as it is marked weak
due to being inline. Due to use of -fvisibility=hidden, symbol for
custom error category is not exported.

To generate ELF object B using header only library X which defines a
custom error category, the linker chooses any one of the implementations
of that error category in the object files linked as it is marked weak
due to being inline. Due to use of -fvisibility=hidden, symbol for
custom error category is not exported.

Program C links against ELF object A and ELF object B. There are now two
instances of the same category object, and their addresses will not
equal. Possible solution: Mark custom error category retrieval function
with default visibility?

That will work with RTLD_GLOBAL. But what if a SO is loaded with
RTLD_LOCAL? That establishes multiple global symbol tables, and once
again two instances of the same error category appear.

The exact same problem applies to the RTTI used to catch exception
throws. The problem was fixed on libstdc++ by using string comparison to
compare RTTI if address comparison failed. libc++ used to noisily take a
stand against string comparison and insist on address comparison, but
they may since have buckled under the constant bugs about exceptions not
being caught.

> You have mentioned both memory barriers and RTLD_LOCAL which seem to
> imply different problems (concurrency versus relocation of weak
> symbols.)

MSVC has the advantage of controlling its ABI. They invented a thing
called _Immortalize which gets specially treated by the linker to
instantiate exactly one of the thing ever in a process. As the VS2015
source file says, /* MAGIC */. Because multiple threads could reach the
instantiation concurrently, it needs to be a memory barrier so one gets
chosen and the others wait.

> Please notice that I am interested in singletons in general, not only
> error categories.

PE and MachO are the least affected by this problem because their
creators thought of symbol encapsulation in advance. ELF is severely
affected by it. The fault is in the ELF spec which assumes a globally
visible unique symbol table. I have tried raising this problem with
those responsible for ELF on a number of occasions in the past, it was
considered not a problem for the linker and ELF folk, they felt it was a
C++ problem. Attempting to explain this was not a problem in PE nor
MachO nor many other binary formats got me nowhere.

Niall

--
ned Productions Limited Consulting
http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users



If you reply to this email, your message will be added to the discussion below:
http://boost.2283326.n4.nabble.com/Compare-boost-system-error-category-tp4692861p4692952.html
To unsubscribe from Compare boost::system::error_category, click here.
NAML

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Compare boost::system::error_category

Boost - Users mailing list
On 25/03/2017 23:05, Christopher Pisz via Boost-users wrote:
> What would be so wrong with category being an actual number to
> compare against?
>
> I don't know anyone whom creates classes and operator == using the
> address of that class. You guys talk about the standard and what
> not, and admittedly I've never looked inside how they implement
> things, but I've never had such problems using the STL either.

C++ 14 standard subsection 19.5.1.1:

"error_category objects are passed by reference, and two such objects
are equal if they have the same address. This means that applications
using custom error_category types should create a single object of each
such type."

Indeed subsection 19.5.1.3 explicitly says that the comparison operator
returns (this == &rhs). That puts standard library implementators in a bind.

Niall

--
ned Productions Limited Consulting
http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Compare boost::system::error_category

Boost - Users mailing list
In reply to this post by Christopher Pisz
On 03/26/2017 12:24 AM, Niall Douglas via Boost-users wrote:

> Indeed subsection 19.5.1.3 explicitly says that the comparison operator
> returns (this == &rhs). That puts standard library implementators in a bind.

It does. You should consider submitting a defect to LWG with the
excellent description to wrote in your earlier reply.

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Compare boost::system::error_category

Boost - Users mailing list
In reply to this post by Boost - Users mailing list
On 03/26/2017 12:05 AM, Christopher Pisz via Boost-users wrote:
> What would be so wrong with category being an actual number to compare
> against?

The challenge is to select a number for a category that is globally
unique across translation units.

The error equality operators use the address of a singleton as this
unique number.

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Compare boost::system::error_category

Boost - Users mailing list
In reply to this post by Boost - Users mailing list
On 3/25/17 7:24 PM, Niall Douglas via Boost-users wrote:

> On 25/03/2017 23:05, Christopher Pisz via Boost-users wrote:
>> What would be so wrong with category being an actual number to
>> compare against?
>>
>> I don't know anyone whom creates classes and operator == using the
>> address of that class. You guys talk about the standard and what
>> not, and admittedly I've never looked inside how they implement
>> things, but I've never had such problems using the STL either.
> C++ 14 standard subsection 19.5.1.1:
>
> "error_category objects are passed by reference, and two such objects
> are equal if they have the same address. This means that applications
> using custom error_category types should create a single object of each
> such type."
>
> Indeed subsection 19.5.1.3 explicitly says that the comparison operator
> returns (this == &rhs). That puts standard library implementators in a bind.
>
> Niall
>
My guess is that the creators of the standard expect that implementers,
and library creators will take the effort to explicitly create their
error objects to allow them to really be unique. I think this means that
in the presence of things like DLLs in windows and the like, a header
only library doesn't work without special help from the linker, as you
really need to move such objects into a special DLL to keep them unique,
or the library loader needs to be given the references to this object
and it picks one of them to satisfy all the references, ignoring the
other definitions.

For the standard library, this isn't as much of an issue, as it already
needs a compiled module, so there is a spot to put them, it just says
that if you might have troubles staticly linking to parts of the
standard library if you are building such a loadable module, all
loadable modules need to refer to the standard library via a loadable
module to keep things unique. The issue becomes for library creators who
want to try to build a 'header only' library.

--
Richard Damon

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Compare boost::system::error_category

Boost - Users mailing list
In reply to this post by Boost - Users mailing list
>> Indeed subsection 19.5.1.3 explicitly says that the comparison operator
>> returns (this == &rhs). That puts standard library implementators in a
>> bind.
>
> It does. You should consider submitting a defect to LWG with the
> excellent description to wrote in your earlier reply.

Sorry, probably I wasn't clear: I *have* raised this with the committee
already, albeit informally. They are well aware of the problems
introduced by the use of shared objects on ELF in practice.

The problem is that C++ says nothing about shared object binaries.
Implicit throughout the standard is the assumption that monolithic
binaries are the sole thing ever produced by a linker, period, and in
that use case the standard mandated behaviour works perfectly. If you do
anything with C++ that is not generating a monolithic executable, you
are officially in UB land where monsters such as the problem described
lurk. You are *on your own*, and this is despite most C++ programmers
are in this UB land on a daily basis.

It is unfortunate that the Modules TS intentionally says absolutely
nothing about shared binaries. It could have been an opportunity to fix
these issues. But objections to that part of earlier proposals was
objected to very early, and they got dropped swiftly.

Niall

--
ned Productions Limited Consulting
http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Compare boost::system::error_category

Boost - Users mailing list
On 3/26/17 5:38 PM, Niall Douglas via Boost-users wrote:

>>> Indeed subsection 19.5.1.3 explicitly says that the comparison operator
>>> returns (this == &rhs). That puts standard library implementators in a
>>> bind.
>> It does. You should consider submitting a defect to LWG with the
>> excellent description to wrote in your earlier reply.
> Sorry, probably I wasn't clear: I *have* raised this with the committee
> already, albeit informally. They are well aware of the problems
> introduced by the use of shared objects on ELF in practice.
>
> The problem is that C++ says nothing about shared object binaries.
> Implicit throughout the standard is the assumption that monolithic
> binaries are the sole thing ever produced by a linker, period, and in
> that use case the standard mandated behaviour works perfectly. If you do
> anything with C++ that is not generating a monolithic executable, you
> are officially in UB land where monsters such as the problem described
> lurk. You are *on your own*, and this is despite most C++ programmers
> are in this UB land on a daily basis.
>
> It is unfortunate that the Modules TS intentionally says absolutely
> nothing about shared binaries. It could have been an opportunity to fix
> these issues. But objections to that part of earlier proposals was
> objected to very early, and they got dropped swiftly.
>
> Niall
>
There is nothing about a shared binary environment that says you are by
definition in the Undefined Behavior territory. The question becomes is
the implementation (fully) conforming when generating programs in this
form. (It can't be UB, as you can generate the problems with a strictly
conforming program, which by definition can't have undefined behavior)
There definitely are challenges to being conforming in this environment,
and the cost to be conforming may be higher than is desired. One
solution to the issue is that if your shared library include code that
came about by a 'weak' definition (one that multiple definitions are
allowed to be generated, but only one placed in the final output), then
the library needs to be broken into several smaller libraries, were each
group of weak symbols gets moved into its own shared library, in a way
the this piece can be match with the same definition from another shared
library that also was possibly put into its own shared library.

--
Richard Damon

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
12
Loading...