comparison test/callback_plain_c++/test_main.cc @ 555:214c4efc104f

- test/callback_plain_c++: added check and a slightly different test for C++ copy-elision/retval-optimization, as C++ finds ambiguities totally ok
author Tassilo Philipp
date Mon, 20 Jun 2022 17:42:13 +0200
parents ca28e9e3c644
children b36a738c8975
comparison
equal deleted inserted replaced
554:4d87bd4890b0 555:214c4efc104f
38 float t; 38 float t;
39 }; 39 };
40 40
41 struct NonTriv { 41 struct NonTriv {
42 int i, j; 42 int i, j;
43 NonTriv(int a, int b) : i(a),j(b) { } 43 static int a, b;
44 NonTriv(const NonTriv& rhs) { static int a=13, b=37; i = a++; j = b++; } 44 NonTriv(int a, int b) : i(a),j(b) { printf("%s\n", "NonTriv::NonTriv(int,int) called"); }
45 NonTriv(const NonTriv& rhs) { printf("%s\n", "NonTriv::NonTriv(const NonTriv&) called"); i = a++; j = b++; }
45 }; 46 };
47 int NonTriv::a = 13;
48 int NonTriv::b = 37;
49
46 50
47 51
48 char cbNonTrivAggrArgHandler(DCCallback* cb, DCArgs* args, DCValue* result, void* userdata) 52 char cbNonTrivAggrArgHandler(DCCallback* cb, DCArgs* args, DCValue* result, void* userdata)
49 { 53 {
50 int* ud = (int*)userdata; 54 int* ud = (int*)userdata;
65 dcbArgAggr(args, (DCpointer)&arg4); printf("4th argument: %f\n", arg4.t); 69 dcbArgAggr(args, (DCpointer)&arg4); printf("4th argument: %f\n", arg4.t);
66 arg5 = dcbArgDouble(args); printf("5th argument: %f\n", arg5); 70 arg5 = dcbArgDouble(args); printf("5th argument: %f\n", arg5);
67 71
68 // the non-triv aggregate members are 14, 38 and 15, 39, respectively, b/c of 72 // the non-triv aggregate members are 14, 38 and 15, 39, respectively, b/c of
69 // copy-ctor call on *passing* them to this handler (not b/c of assignment 73 // copy-ctor call on *passing* them to this handler (not b/c of assignment
70 // operator, above); see below on where 13 and 37 are initialized 74 // operator, above); see above where 13 and 37 are initialized
71 result->d = *ud + arg1 + arg2.i + arg2.j + arg3.i + arg3.j + arg4.t + arg5; 75 result->d = *ud + arg1 + arg2.i + arg2.j + arg3.i + arg3.j + arg4.t + arg5;
72 return 'd'; 76 return 'd';
73 } 77 }
74 78
75 79
76 int testNonTrivAggrArgsCallback() 80 int testNonTrivAggrArgsCallback()
77 { 81 {
78 DCCallback* cb; 82 DCCallback* cb;
79 Triv t = { 1.75f }; 83 Triv t = { 1.75f };
80 NonTriv a(1, 2); 84 NonTriv a(1, 2);
81 NonTriv b(a); // this sets NonTriv's statics a = 13 and b = 37 85 NonTriv b(a);
82 86
83 int ret = 1; 87 int ret = 1;
84 double result = 0; 88 double result = 0;
85 int userdata = 1337; 89 int userdata = 1337;
86 90
94 98
95 result = ((double(*)(int, NonTriv, NonTriv, Triv, double))cb)(123, a, b, t, 4.5); 99 result = ((double(*)(int, NonTriv, NonTriv, Triv, double))cb)(123, a, b, t, 4.5);
96 dcbFreeCallback(cb); 100 dcbFreeCallback(cb);
97 101
98 printf("successfully returned from callback\n"); 102 printf("successfully returned from callback\n");
99 printf("return value (should be 1572.25): %f\n", result); 103 printf("retval (should be 1572.25): %f\n", result);
100 104
101 ret = result == 1572.25 && ret; 105 ret = result == 1572.25 && ret;
102 106
103 return ret; 107 return ret;
104 } 108 }
122 { 126 {
123 DCCallback* cb; 127 DCCallback* cb;
124 DCaggr *aggrs[1] = { NULL }; // one non-triv aggr 128 DCaggr *aggrs[1] = { NULL }; // one non-triv aggr
125 cb = dcbNewCallback2(")A", &cbNonTrivAggrReturnHandler, NULL, aggrs); 129 cb = dcbNewCallback2(")A", &cbNonTrivAggrReturnHandler, NULL, aggrs);
126 130
127 NonTriv result = ((NonTriv(*)())cb)(); 131 NonTriv result = ((NonTriv(*)())cb)(); // potential copy elision on construction
132
133 int a = NonTriv::a-1;
134 int b = NonTriv::b-1;
135 printf("successfully returned from callback 1/2\n");
136 printf("retval w/ potential retval optimization and copy-init (should be %d %d for init or %d %d for copy, both allowed by C++): %d %d\n", 1, 3, a, b, result.i, result.j);
137
138 ret = ((result.i == 1 && result.j == 3) || (result.i == a && result.j == b)) && ret;
139
140 // avoid copy elision on construction
141 result.i = result.j = -77;
142 result = ((NonTriv(*)())cb)(); // potential copy elision
143
144 a = NonTriv::a-1;
145 b = NonTriv::b-1;
146 printf("successfully returned from callback 2/2\n");
147 printf("retval w/ potential retval optimization and copy-init (should be %d %d for init or %d %d for copy, both allowed by C++): %d %d\n", 1, 3, a, b, result.i, result.j);
128 148
129 dcbFreeCallback(cb); 149 dcbFreeCallback(cb);
130 150
131 printf("successfully returned from callback\n"); 151 ret = ((result.i == 1 && result.j == 3) || (result.i == a && result.j == b)) && ret;
132 printf("return value (should be %d %d): %d %d\n", 1, 3, result.i, result.j);
133
134 ret = result.i == 1 && result.j == 3 && ret;
135 } 152 }
136 153
137 return ret; 154 return ret;
138 } 155 }
139 #endif 156 #endif