https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63907
David Vitek changed:
What|Removed |Added
CC||dvitek at grammatech dot com
--- Comment #11 from David Vitek ---
I ran into this and figured out a solution. There are actually two different
issues at play depending on which version of g++ is trying to build rwlock.cc.
g++ 7.3 can't deal with PTHREAD_COND_INITIALIZER being surrounded by parens in
the initializer list. If we take away the parens, it parses great with g++
7.3. I suspect this could be fixed in version control. Specifically, the
string literal in the older definition of PTHREAD_COND_INITIALIZER does not
want to be converted to a character array.
g++ 4.5.3 refuses to parse any formulation I've been able to think of unless I
make the initializer list completely empty. It just so happens that
PTHREAD_COND_INITIALIZER is a zero initializer with my libc, so the empty
initializer list is sufficient but abstraction-breaking. You couldn't safely
commit this workaround to version control.
Details:
PTHREAD_COND_INITIALIZER expands to {{ 0, 0 }, 0, "", 0}
Here is the definition of pthread_cond_t:
struct _pthread_fastlock
{
long int __status;
int __spinlock;
};
typedef struct _pthread_descr_struct *_pthread_descr;
__extension__ typedef long long __pthread_cond_align_t;
typedef struct
{
struct _pthread_fastlock __c_lock;
_pthread_descr __c_waiting;
char __padding[48 - sizeof (struct _pthread_fastlock)
- sizeof (_pthread_descr) - sizeof (__pthread_cond_align_t)];
__pthread_cond_align_t __align;
} pthread_cond_t;
struct S{
pthread_cond_t x;
/* g++ 7.3: error: no matching function for call to
'pthread_cond_t::pthread_cond_t()'
* g++ 4.5.3: error: could not convert '{{0, 0}, 0, "", 0}' to
'pthread_cond_t'
*/
S() : x (PTHREAD_COND_INITIALIZER) {}
};
// Now without the parens:
struct S{
pthread_cond_t x;
/* g++ 7.3: Success!
* g++ 4.5.3: error: could not convert '{{0, 0}, 0, "", 0}' to
'pthread_cond_t'
*/
S() : x PTHREAD_COND_INITIALIZER {}
};
Here are some stand-alone diagnostics that elucidate the root cause:
g++ 4.5.3 can't handle this code even with -std=gnu++0x. I wasn't able to come
up with anything viable here besides {}.
struct S{
struct inner{
char A[1];
} x;
/* could not convert '{{0}}' to 'S::inner' */
S() : x {{0}} {};
};
g++ 7.3 doesn't like this:
struct R{
struct inner{
char __padding[1];
} x;
/* error: no matching function for call to 'R::inner::inner()' */
R() : x ({""}) {};
};
but it does like this:
struct R{
struct inner{
char __padding[1];
} x;
// OK
R() : x {""} {};
};
Two patches forthcoming...