-edit- Я сузил его. Воспроизводимый: почему передача этого объекта в C нарушает мой код?
Мое приложение не работает должным образом после внесения изменений. Я получил предупреждение в MSVC, но не в GCC.
Вот репо предупреждения.
предупреждение C4190: для 'fnA' задана C-связь, но возвращается UDT 'Test', который несовместим с C
#include <type_traits>
template<class T>
class Test{
T t;
};
typedef Test<int> A;
//static_assert(std::is_pod<A>::value, "Not a POD"); //fails in msvc 2010
static_assert(sizeof(A) == sizeof(int), "");
static_assert(sizeof(A) == sizeof(void*), "");
extern "C" {
A fnA(A v) { return v; }
}
int main() {
A a;
fnA(a);
}
AFAIK не должно быть никаких причин, по которым я не могу использовать Test в качестве возвращаемого значения; Это может не быть проблемой, но это может быть проблемой. Я не могу понять проблему, но я получаю странные странности, которые я не могу воспроизвести (как gcc, так и msvc). Я подозревал, что проблема в том, что MyString поврежден, но, похоже, это не тот случай, который меня очень смутил. Вот моя обертка. MyString> 8 байтов, и мне нужно передать это коду C, который, к сожалению, возвращает все int. Вот почему я поставил static assert, чтобы увидеть, соответствует ли размер класса тому, что я ожидал. Теперь, когда размер / сплайсинг обработан, я все еще как WTF!?! Почему существует это предупреждение, и могу ли я что-нибудь сделать, чтобы это исправить?
Даже запись class Test{ T t; };
вызывает предупреждение, однако структура исправляет его. структура с частными разрывами это, и мне нужно, чтобы быть частным.
OK! После того, как я удалил конструкторы в WrappedPointer и изменил класс на struct (что делает lhs общедоступным). Отлично работает в GCC и MSVC. Изменение struct WrappedPointer
на class WrappedPointer
нарушает мой код. WTF!?! Это тоже отладочная сборка, не оптимизированная. С какой стати изменение структуры ключевого слова на класс нарушает код!?! WTF!?! НО это изменение не нарушает GCC. Использование конструкторов не по умолчанию break gcc ...
template <class T>
struct WrappedPointer {
//private:
T* lhs;
public:
void SetLHS(T*v) { lhs=v; }
//WrappedPointer(){}
//WrappedPointer(T*value) : lhs(value){}
//WrappedPointer(const WrappedPointer&v) : lhs(v.lhs){}
T* operator->() const { return lhs; }
T* operator*() const { return lhs; }
template<class TT>
bool operator==(TT t) const { return *lhs==t; }
template<class TT>
bool operator!=(TT t) const { return *lhs!=t; }
bool operator==(int v) const { myassert2(v==0); return lhs==0; }
bool operator!=(int v) const { myassert2(v==0); return lhs!=0; }
bool operator==(const WrappedPointer&t) const { return *lhs==*t; }
bool operator!=(const WrappedPointer&t) const { return *lhs!=*t; }
}
typedef WrappedPointer<MyString> String;
//typedef MyString* String;
static_assert(sizeof(String) == sizeof(int), "");
static_assert(sizeof(String) == sizeof(void*),"");