Issue Details (XML | Word | Printable)

Key: STDCXX-643
Type: Bug Bug
Status: Open Open
Priority: Major Major
Assignee: Unassigned
Reporter: Travis Vitek
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
C++ Standard Library

[IBM XLC++/AIX] std::exception incompatible with runtime library

Created: 02/Nov/07 10:27 PM   Updated: 11/Jul/09 12:07 AM
Return to search
Component/s: 19. Diagnostics
Affects Version/s: 4.2.0
Fix Version/s: 5.0.0

Time Tracking:
Not Specified

Environment: IBM XLC++/AIX
Issue Links:
Blocker
 

Severity: Binary Incompatibility


 Description  « Hide
A description of the problem is available here.
http://www.nabble.com/19.exceptions.mt.cpp-fails-on-AIX-tf4738595.html

Essentially we need to add a const char* member to std::exception for AIX. Unfortunately the fix is a binary incompatible with previous versions of stdcxx.



 All   Comments   Work Log   Change History   Subversion Commits      Sort Order: Ascending order - Click to sort in descending order
Travis Vitek added a comment - 27/Mar/08 07:04 AM - edited
I've already suggested that we try to determine, at configuration time, the size and layout of the exception classes so that we can emulate them. If we don't go that far, we should at least add something that will check that the sizes match up and force the library to not compile if they don't. Something like this...
// looking for runtime library exceptions

#include <exception>
#include <typeinfo>

#include <stdio.h>

template <class T>
void run_test (const char* s)
{
  printf ("#define %-18s %u\n", s, sizeof (T));
}

int main ()
{
#define TEST(s,t) run_test<t>(#s)

  TEST (_RWSTD_EXCEPTION_SIZE     , std::exception);
  TEST (_RWSTD_BAD_ALLOC_SIZE     , std::bad_alloc);
  TEST (_RWSTD_BAD_CAST_SIZE      , std::bad_cast);
  TEST (_RWSTD_BAD_EXCDEPTION_SIZE, std::bad_exception);
  TEST (_RWSTD_BAD_TYPEID_SIZE    , std::bad_typeid);

  return 0;
}

Then we would put something like this near the top of exception.cpp

_RWSTD_NAMESPACE (__rw) {

static void
__rw_exception_compile_asserts ()
{
#define TEST(s,t) _RWSTD_COMPILE_ASSERT (s == sizeof (t))
  TEST (_RWSTD_EXCEPTION_SIZE     , std::exception);
  TEST (_RWSTD_BAD_ALLOC_SIZE     , std::bad_alloc);
  TEST (_RWSTD_BAD_CAST_SIZE      , std::bad_cast);
  TEST (_RWSTD_BAD_EXCDEPTION_SIZE, std::bad_exception);
  TEST (_RWSTD_BAD_TYPEID_SIZE    , std::bad_typeid);
#undef TEST
}

} // namespace rw

Martin Sebor added a comment - 27/Mar/08 03:28 PM
I agree that testing this is great idea. I think we might as well hardcode the sizes of all the exception classes for each known compiler into the test itself:
#ifdef __VACPP__
    assert (sizeof (std::bad_alloc)) == 2 * sizeof (char*));
    assert (sizeof (std::bad_cast)) == 2 * sizeof (char*));
    assert (sizeof (std::bad_exception)) == 2 * sizeof (char*));
    assert (sizeof (std::bad_typeid)) == 2 * sizeof (char*));
    assert (sizeof (std::exception)) == 2 * sizeof (char*));
#elif defined (__HP_aCC)
    assert (sizeof (std::bad_alloc)) == sizeof (char*));
    assert (sizeof (std::bad_cast)) ==  sizeof (char*));
    assert (sizeof (std::bad_exception)) == sizeof (char*));
    assert (sizeof (std::bad_typeid)) == sizeof (char*));
    assert (sizeof (std::exception)) == sizeof (char*));
#elif defined __GNUC__
    assert (sizeof (std::bad_alloc)) == sizeof (char*));
    assert (sizeof (std::bad_cast)) ==  sizeof (char*));
    assert (sizeof (std::bad_exception)) == sizeof (char*));
    assert (sizeof (std::bad_typeid)) == sizeof (char*));
    assert (sizeof (std::exception)) == sizeof (char*));
#else
    // ...
#endif

Travis Vitek added a comment - 27/Mar/08 06:29 PM
I'm assuming that you are talking about asserting the size of the runtime library exceptions in a configuration test, is that right? If so, what happens if the config test fails? Without something else, nobody will notice unless they are actually looking for the failure message in the configuration spew. I guess that we could use the configuration test to set a macro like _RWSTD_NO_EXCEPTION_BROKEN, and then in the library we could assert at compile time that the macro is defined. That way the library will fail to build if we don't know the proper sizes for the exception classes. The problem with this is that we have to hardcode the correct values for all compilers we know. This config test, and the implementation, would need to be ported for any new environment that we wanted to support or that our users would want to use.

I think an ideal solution would be to do something to guarantee that these objects are of the correct size, even for compilers that we don't officially support. We already do it for things like struct lconv and struct tm, why not std::exception?


Martin Sebor added a comment - 27/Mar/08 06:45 PM
I meant in a regular test (not a config one). But you're right, that may not be enough. Similarly, asserting the same conditions in a config test wouldn't be enough unless the test's failure caused the whole configuration process to fail. We don't have a mechanism like that in place but we've had the need for it in the past so enhancing the config infrastructure might be the way to go. The other approach you suggest – to #define a macro like _RWSTD_NO_EXCEPTION_BROKEN and then asserting that it's #defined (or preferably the other way around so as not to introduce unnecessary macros) would also work.

That said, if as you say we already have a solution in place for other types (I forgot about struct lconv and struct tm), we might as well use it.


Martin Sebor added a comment - 27/Mar/08 09:20 PM
This issue is specific to IBM XLC++ on AIX (as opposed to Linux).
Added a platform tag to Summary and updated Environment.

Martin Sebor added a comment - 17/Jul/08 11:54 PM
Assigned to Travis.