Thanks to @user2079303 for the Coliru resource and test code.
I've now got code that demonstrates this issue when compiled with VS2013 - it works fine when compiled on Coliru, so it's definitely as VS2013 compiler problem. As @user2079303 correctly suggested the previous code did NOT have the error.
The issue appears to be having a wrapper function around the array access before the copy to result:
SWIGINTERN ConGroup ConGroupArray_getitem(ConGroup *self, int index){
return self[index];
}
SWIGEXPORT void * SWIGSTDCALL CSharp_ConGroupArray_getitem(void * jarg1, int jarg2) {
void * jresult;
ConGroup *arg1 = (ConGroup *)0;
int arg2;
ConGroup result;
arg1 = (ConGroup *)jarg1;
arg2 = (int)jarg2;
result = ConGroupArray_getitem(arg1, arg2);
// result = arg1[arg2];
jresult = new ConGroup((const ConGroup &)result);
return jresult;
}
Here's a link to Coliru that has the modified source: Coliru Example
If run on Coliru it works fine, BUT when build with VS2013 in a C++ console app with CLR turned on it fails.
I'm struggling to explain some very strange behaviour that I've been seeing with copy constructors in VS2013, and I'm wondering if any of you have seen anything similar and can shed any light on it.
I've been wrapping a 3rd party C++ DLL using SWIG and was having problems with getting valid data out of a specific structure.
The 3rd party DLL exposes all of its data via POD structures defined in the API header file and most where working fine - giving me valid data, however, a few appeared broken and were producing invalid data.
After much debugging eventually I discovered that replacing the compiler generated copy constructor with my own that simply uses memcpy solves the problem.
The question is really about what can possible be going wrong?
How can a compiler generated copy constructor be going wrong without generating any errors?
As far as I can tell there's nothing particularly different about the struct that doesn't work when compared to one that does... so I'm happy to confess to being highly confused.
Here's the structure in question, and the structures it contains, with my added copy constructor:
struct ConGroupSec
{
int show,trade;
int execution;
double comm_base;
int comm_type;
int comm_lots;
double comm_agent;
int comm_agent_type;
int spread_diff;
int lot_min,lot_max;
int lot_step;
int ie_deviation;
int confirmation;
int trade_rights;
int ie_quick_mode;
int autocloseout_mode;
double comm_tax;
int comm_agent_lots;
int freemargin_mode;
int reserved[3];
};
struct ConGroupMargin
{
char symbol[12];
double swap_long,swap_short;
double margin_divider;
int reserved[7];
};
struct ConGroup
{
char group[16];
int enable;
int timeout;
int adv_security;
char company[128];
char signature[128];
char support_page[128];
char smtp_server[64];
char smtp_login[32];
char smtp_password[32];
char support_email[64];
char templates[32];
int copies;
int reports;
int default_leverage;
double default_deposit;
int maxsecurities;
ConGroupSec secgroups[32];
ConGroupMargin secmargins[128];
int secmargins_total;
char currency[12];
double credit;
int margin_call;
int margin_mode;
int margin_stopout;
double interestrate;
int use_swap;
int news;
int rights;
int check_ie_prices;
int maxpositions;
int close_reopen;
int hedge_prohibited;
int close_fifo;
int hedge_largeleg;
int unused_rights[2];
char securities_hash[16];
int margin_type;
int archive_period;
int archive_max_balance;
int stopout_skip_hedged;
int archive_pending_period;
UINT news_languages[8];
UINT news_languages_total;
int reserved[17];
ConGroup() {}
ConGroup(const ConGroup& src)
{
memcpy(this, &src, sizeof(ConGroup));
}
};
When the constructors are commented out, the struct is not copied correctly, when commented back in things work fine.
Can anyone out there explain this? I can't.
As requested here's the code that actually uses the copy constructor:
SWIGEXPORT void * SWIGSTDCALL CSharp_ConGroupArray_getitem(void * jarg1, int jarg2) {
void * jresult ;
ConGroup *arg1 = (ConGroup *) 0 ;
int arg2 ;
ConGroup result;
arg1 = (ConGroup *)jarg1;
arg2 = (int)jarg2;
result = arg1[arg2];
jresult = new ConGroup((const ConGroup &)result);
return jresult;
}
This is code generated by SWIG, and is part of a managed C++ wrapper class for the native 3rd party DLL.
In the VS2013 debugger, I can see that arg1 is a valid array of ConGroup structures that contain valid data and doing manual pointer arithmetic in the memory window allowed me to check that for a number of the array contents.
As it happens I've worked around the issue by changing the code above to the following, which removes the copying entirely:
SWIGEXPORT void * SWIGSTDCALL CSharp_ConGroupArray_getitem(void * jarg1, int jarg2) {
void * jresult ;
ConGroup *arg1 = (ConGroup *) 0 ;
int arg2 ;
ConGroup* result;
arg1 = (ConGroup *)jarg1;
arg2 = (int)jarg2;
result = &arg1[arg2];
jresult = (void*)result;
return jresult;
}
That code works perfectly, so valid data does exist at the correct locations, hence I believe the issue must be a copy constructor problem...
Time to close this question.
It seems the issue here is entirely related to having the CLR enabled on a C++ project. Enabling the CLR appears the alter the way the copy default constructors work within the C++ code when using Visual Studio 2013 and 2015.
Given that could be better phrased as a new question I'm closing this one.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.