1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_cppu.hxx" 30 31 #include <cstddef> 32 #include <stdio.h> 33 34 #include "cppu/macros.hxx" 35 36 #include "osl/mutex.hxx" 37 38 #include "constr.hxx" 39 #include "destr.hxx" 40 #include "copy.hxx" 41 #include "assign.hxx" 42 #include "eq.hxx" 43 44 #include "boost/static_assert.hpp" 45 46 47 using namespace ::cppu; 48 using namespace ::rtl; 49 using namespace ::osl; 50 51 52 namespace cppu 53 { 54 55 // Sequence<>() (default ctor) relies on this being static: 56 uno_Sequence g_emptySeq = { 1, 0, { 0 } }; 57 typelib_TypeDescriptionReference * g_pVoidType = 0; 58 59 //-------------------------------------------------------------------------------------------------- 60 void * binuno_queryInterface( void * pUnoI, typelib_TypeDescriptionReference * pDestType ) 61 { 62 // init queryInterface() td 63 static typelib_TypeDescription * g_pQITD = 0; 64 if (0 == g_pQITD) 65 { 66 MutexGuard aGuard( Mutex::getGlobalMutex() ); 67 if (0 == g_pQITD) 68 { 69 typelib_TypeDescriptionReference * type_XInterface = 70 * typelib_static_type_getByTypeClass( typelib_TypeClass_INTERFACE ); 71 typelib_InterfaceTypeDescription * pTXInterfaceDescr = 0; 72 TYPELIB_DANGER_GET( (typelib_TypeDescription **) &pTXInterfaceDescr, type_XInterface ); 73 OSL_ASSERT( pTXInterfaceDescr->ppAllMembers ); 74 typelib_typedescriptionreference_getDescription( 75 &g_pQITD, pTXInterfaceDescr->ppAllMembers[ 0 ] ); 76 TYPELIB_DANGER_RELEASE( (typelib_TypeDescription *) pTXInterfaceDescr ); 77 } 78 } 79 80 uno_Any aRet, aExc; 81 uno_Any * pExc = &aExc; 82 void * aArgs[ 1 ]; 83 aArgs[ 0 ] = &pDestType; 84 (*((uno_Interface *) pUnoI)->pDispatcher)( 85 (uno_Interface *) pUnoI, g_pQITD, &aRet, aArgs, &pExc ); 86 87 uno_Interface * ret = 0; 88 if (0 == pExc) 89 { 90 typelib_TypeDescriptionReference * ret_type = aRet.pType; 91 switch (ret_type->eTypeClass) 92 { 93 case typelib_TypeClass_VOID: // common case 94 typelib_typedescriptionreference_release( ret_type ); 95 break; 96 case typelib_TypeClass_INTERFACE: 97 // tweaky... avoiding acquire/ release pair 98 typelib_typedescriptionreference_release( ret_type ); 99 ret = (uno_Interface *) aRet.pReserved; // serving acquired interface 100 break; 101 default: 102 _destructAny( &aRet, 0 ); 103 break; 104 } 105 } 106 else 107 { 108 #if OSL_DEBUG_LEVEL > 1 109 OUStringBuffer buf( 128 ); 110 buf.appendAscii( 111 RTL_CONSTASCII_STRINGPARAM("### exception occured querying for interface ") ); 112 buf.append( * reinterpret_cast< OUString const * >( &pDestType->pTypeName ) ); 113 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(": [") ); 114 buf.append( * reinterpret_cast< OUString const * >( &pExc->pType->pTypeName ) ); 115 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] ") ); 116 // Message is very first member 117 buf.append( * reinterpret_cast< OUString const * >( pExc->pData ) ); 118 OString cstr( 119 OUStringToOString( buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) ); 120 OSL_ENSURE( 0, cstr.getStr() ); 121 #endif 122 uno_any_destruct( pExc, 0 ); 123 } 124 return ret; 125 } 126 127 //================================================================================================== 128 void defaultConstructStruct( 129 void * pMem, 130 typelib_CompoundTypeDescription * pCompType ) 131 SAL_THROW( () ) 132 { 133 _defaultConstructStruct( pMem, pCompType ); 134 } 135 //================================================================================================== 136 void copyConstructStruct( 137 void * pDest, void * pSource, 138 typelib_CompoundTypeDescription * pTypeDescr, 139 uno_AcquireFunc acquire, uno_Mapping * mapping ) 140 SAL_THROW( () ) 141 { 142 _copyConstructStruct( pDest, pSource, pTypeDescr, acquire, mapping ); 143 } 144 //================================================================================================== 145 void destructStruct( 146 void * pValue, 147 typelib_CompoundTypeDescription * pTypeDescr, 148 uno_ReleaseFunc release ) 149 SAL_THROW( () ) 150 { 151 _destructStruct( pValue, pTypeDescr, release ); 152 } 153 //================================================================================================== 154 sal_Bool equalStruct( 155 void * pDest, void *pSource, 156 typelib_CompoundTypeDescription * pTypeDescr, 157 uno_QueryInterfaceFunc queryInterface, uno_ReleaseFunc release ) 158 SAL_THROW( () ) 159 { 160 return _equalStruct( pDest, pSource, pTypeDescr, queryInterface, release ); 161 } 162 //================================================================================================== 163 sal_Bool assignStruct( 164 void * pDest, void * pSource, 165 typelib_CompoundTypeDescription * pTypeDescr, 166 uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release ) 167 SAL_THROW( () ) 168 { 169 return _assignStruct( pDest, pSource, pTypeDescr, queryInterface, acquire, release ); 170 } 171 172 //============================================================================== 173 uno_Sequence * copyConstructSequence( 174 uno_Sequence * pSource, 175 typelib_TypeDescriptionReference * pElementType, 176 uno_AcquireFunc acquire, uno_Mapping * mapping ) 177 { 178 return icopyConstructSequence( pSource, pElementType, acquire, mapping ); 179 } 180 181 //============================================================================== 182 void destructSequence( 183 uno_Sequence * pSequence, 184 typelib_TypeDescriptionReference * pType, 185 typelib_TypeDescription * pTypeDescr, 186 uno_ReleaseFunc release ) 187 { 188 idestructSequence( pSequence, pType, pTypeDescr, release ); 189 } 190 191 //================================================================================================== 192 sal_Bool equalSequence( 193 uno_Sequence * pDest, uno_Sequence * pSource, 194 typelib_TypeDescriptionReference * pElementType, 195 uno_QueryInterfaceFunc queryInterface, uno_ReleaseFunc release ) 196 SAL_THROW( () ) 197 { 198 return _equalSequence( pDest, pSource, pElementType, queryInterface, release ); 199 } 200 201 extern "C" 202 { 203 //################################################################################################## 204 void SAL_CALL uno_type_constructData( 205 void * pMem, typelib_TypeDescriptionReference * pType ) 206 SAL_THROW_EXTERN_C() 207 { 208 _defaultConstructData( pMem, pType, 0 ); 209 } 210 //################################################################################################## 211 void SAL_CALL uno_constructData( 212 void * pMem, typelib_TypeDescription * pTypeDescr ) 213 SAL_THROW_EXTERN_C() 214 { 215 _defaultConstructData( pMem, pTypeDescr->pWeakRef, pTypeDescr ); 216 } 217 //################################################################################################## 218 void SAL_CALL uno_type_destructData( 219 void * pValue, typelib_TypeDescriptionReference * pType, 220 uno_ReleaseFunc release ) 221 SAL_THROW_EXTERN_C() 222 { 223 _destructData( pValue, pType, 0, release ); 224 } 225 //################################################################################################## 226 void SAL_CALL uno_destructData( 227 void * pValue, 228 typelib_TypeDescription * pTypeDescr, 229 uno_ReleaseFunc release ) 230 SAL_THROW_EXTERN_C() 231 { 232 _destructData( pValue, pTypeDescr->pWeakRef, pTypeDescr, release ); 233 } 234 //################################################################################################## 235 void SAL_CALL uno_type_copyData( 236 void * pDest, void * pSource, 237 typelib_TypeDescriptionReference * pType, 238 uno_AcquireFunc acquire ) 239 SAL_THROW_EXTERN_C() 240 { 241 _copyConstructData( pDest, pSource, pType, 0, acquire, 0 ); 242 } 243 //################################################################################################## 244 void SAL_CALL uno_copyData( 245 void * pDest, void * pSource, 246 typelib_TypeDescription * pTypeDescr, 247 uno_AcquireFunc acquire ) 248 SAL_THROW_EXTERN_C() 249 { 250 _copyConstructData( pDest, pSource, pTypeDescr->pWeakRef, pTypeDescr, acquire, 0 ); 251 } 252 //################################################################################################## 253 void SAL_CALL uno_type_copyAndConvertData( 254 void * pDest, void * pSource, 255 typelib_TypeDescriptionReference * pType, 256 uno_Mapping * mapping ) 257 SAL_THROW_EXTERN_C() 258 { 259 _copyConstructData( pDest, pSource, pType, 0, 0, mapping ); 260 } 261 //################################################################################################## 262 void SAL_CALL uno_copyAndConvertData( 263 void * pDest, void * pSource, 264 typelib_TypeDescription * pTypeDescr, 265 uno_Mapping * mapping ) 266 SAL_THROW_EXTERN_C() 267 { 268 _copyConstructData( pDest, pSource, pTypeDescr->pWeakRef, pTypeDescr, 0, mapping ); 269 } 270 //################################################################################################## 271 sal_Bool SAL_CALL uno_type_equalData( 272 void * pVal1, typelib_TypeDescriptionReference * pVal1Type, 273 void * pVal2, typelib_TypeDescriptionReference * pVal2Type, 274 uno_QueryInterfaceFunc queryInterface, uno_ReleaseFunc release ) 275 SAL_THROW_EXTERN_C() 276 { 277 return _equalData( 278 pVal1, pVal1Type, 0, 279 pVal2, pVal2Type, 0, 280 queryInterface, release ); 281 } 282 //################################################################################################## 283 sal_Bool SAL_CALL uno_equalData( 284 void * pVal1, typelib_TypeDescription * pVal1TD, 285 void * pVal2, typelib_TypeDescription * pVal2TD, 286 uno_QueryInterfaceFunc queryInterface, uno_ReleaseFunc release ) 287 SAL_THROW_EXTERN_C() 288 { 289 return _equalData( 290 pVal1, pVal1TD->pWeakRef, pVal1TD, 291 pVal2, pVal2TD->pWeakRef, pVal2TD, 292 queryInterface, release ); 293 } 294 //################################################################################################## 295 sal_Bool SAL_CALL uno_type_assignData( 296 void * pDest, typelib_TypeDescriptionReference * pDestType, 297 void * pSource, typelib_TypeDescriptionReference * pSourceType, 298 uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release ) 299 SAL_THROW_EXTERN_C() 300 { 301 return _assignData( 302 pDest, pDestType, 0, 303 pSource, pSourceType, 0, 304 queryInterface, acquire, release ); 305 } 306 //################################################################################################## 307 sal_Bool SAL_CALL uno_assignData( 308 void * pDest, typelib_TypeDescription * pDestTD, 309 void * pSource, typelib_TypeDescription * pSourceTD, 310 uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release ) 311 SAL_THROW_EXTERN_C() 312 { 313 return _assignData( 314 pDest, pDestTD->pWeakRef, pDestTD, 315 pSource, pSourceTD->pWeakRef, pSourceTD, 316 queryInterface, acquire, release ); 317 } 318 //################################################################################################## 319 sal_Bool SAL_CALL uno_type_isAssignableFromData( 320 typelib_TypeDescriptionReference * pAssignable, 321 void * pFrom, typelib_TypeDescriptionReference * pFromType, 322 uno_QueryInterfaceFunc queryInterface, uno_ReleaseFunc release ) 323 SAL_THROW_EXTERN_C() 324 { 325 if (::typelib_typedescriptionreference_isAssignableFrom( pAssignable, pFromType )) 326 return sal_True; 327 if (typelib_TypeClass_INTERFACE != pFromType->eTypeClass || 328 typelib_TypeClass_INTERFACE != pAssignable->eTypeClass) 329 { 330 return sal_False; 331 } 332 333 // query 334 if (0 == pFrom) 335 return sal_False; 336 void * pInterface = *(void **)pFrom; 337 if (0 == pInterface) 338 return sal_False; 339 340 if (0 == queryInterface) 341 queryInterface = binuno_queryInterface; 342 void * p = (*queryInterface)( pInterface, pAssignable ); 343 _release( p, release ); 344 return (0 != p); 345 } 346 } 347 348 349 //################################################################################################## 350 //################################################################################################## 351 //################################################################################################## 352 353 354 #if OSL_DEBUG_LEVEL > 1 355 356 #if defined( SAL_W32) 357 #pragma pack(push, 8) 358 #elif defined(SAL_OS2) 359 #pragma pack(push, 4) 360 #endif 361 362 #if defined(INTEL) \ 363 && (defined(__GNUC__) && (defined(LINUX) || defined(FREEBSD) || defined(OS2)) || defined(MACOSX) \ 364 || defined(__SUNPRO_CC) && defined(SOLARIS)) 365 #define MAX_ALIGNMENT_4 366 #endif 367 368 #define OFFSET_OF( s, m ) reinterpret_cast< std::size_t >((char *)&((s *)16)->m -16) 369 370 #define BINTEST_VERIFY( c ) \ 371 if (! (c)) { fprintf( stderr, "### binary compatibility test failed: %s [line %d]!!!\n", #c, __LINE__ ); abort(); } 372 #define BINTEST_VERIFYOFFSET( s, m, n ) \ 373 if (OFFSET_OF(s, m) != n) { fprintf( stderr, "### OFFSET_OF(" #s ", " #m ") = %" SAL_PRI_SIZET "u instead of expected %d!!!\n", OFFSET_OF(s, m), n ); abort(); } 374 375 #if OSL_DEBUG_LEVEL > 1 376 #if defined(__GNUC__) && (defined(LINUX) || defined(FREEBSD)) && (defined(INTEL) || defined(POWERPC) || defined(X86_64) || defined(S390)) 377 #define BINTEST_VERIFYSIZE( s, n ) \ 378 fprintf( stderr, "> sizeof(" #s ") = %d; __alignof__ (" #s ") = %d\n", sizeof(s), __alignof__ (s) ); \ 379 if (sizeof(s) != n) { fprintf( stderr, "### sizeof(" #s ") = %d instead of expected %d!!!\n", sizeof(s), n ); abort(); } 380 #else // ! GNUC 381 #define BINTEST_VERIFYSIZE( s, n ) \ 382 fprintf( stderr, "> sizeof(" #s ") = %d\n", sizeof(s) ); \ 383 if (sizeof(s) != n) { fprintf( stderr, "### sizeof(" #s ") = %d instead of expected %d!!!\n", sizeof(s), n ); abort(); } 384 #endif 385 #else // ! OSL_DEBUG_LEVEL 386 #define BINTEST_VERIFYSIZE( s, n ) \ 387 if (sizeof(s) != n) { fprintf( stderr, "### sizeof(" #s ") = %d instead of expected %d!!!\n", sizeof(s), n ); abort(); } 388 #endif 389 390 struct C1 391 { 392 sal_Int16 n1; 393 }; 394 struct C2 : public C1 395 { 396 sal_Int32 n2 CPPU_GCC3_ALIGN( C1 ); 397 }; 398 struct C3 : public C2 399 { 400 double d3; 401 sal_Int32 n3; 402 }; 403 struct C4 : public C3 404 { 405 sal_Int32 n4 CPPU_GCC3_ALIGN( C3 ); 406 double d4; 407 }; 408 struct C5 : public C4 409 { 410 sal_Int64 n5; 411 sal_Bool b5; 412 }; 413 struct C6 : public C1 414 { 415 C5 c6 CPPU_GCC3_ALIGN( C1 ); 416 sal_Bool b6; 417 }; 418 419 struct D 420 { 421 sal_Int16 d; 422 sal_Int32 e; 423 }; 424 struct E 425 { 426 sal_Bool a; 427 sal_Bool b; 428 sal_Bool c; 429 sal_Int16 d; 430 sal_Int32 e; 431 }; 432 433 struct M 434 { 435 sal_Int32 n; 436 sal_Int16 o; 437 }; 438 439 struct N : public M 440 { 441 sal_Int16 p CPPU_GCC3_ALIGN( M ); 442 }; 443 struct N2 444 { 445 M m; 446 sal_Int16 p; 447 }; 448 449 struct O : public M 450 { 451 double p; 452 sal_Int16 q; 453 }; 454 struct O2 : public O 455 { 456 sal_Int16 p2 CPPU_GCC3_ALIGN( O ); 457 }; 458 459 struct P : public N 460 { 461 double p2; 462 }; 463 464 struct empty 465 { 466 }; 467 struct second : public empty 468 { 469 int a; 470 }; 471 472 struct AlignSize_Impl 473 { 474 sal_Int16 nInt16; 475 double dDouble; 476 }; 477 478 struct Char1 479 { 480 char c1; 481 }; 482 struct Char2 : public Char1 483 { 484 char c2 CPPU_GCC3_ALIGN( Char1 ); 485 }; 486 struct Char3 : public Char2 487 { 488 char c3 CPPU_GCC3_ALIGN( Char2 ); 489 }; 490 struct Char4 491 { 492 Char3 chars; 493 char c; 494 }; 495 class Ref 496 { 497 void * p; 498 }; 499 enum Enum 500 { 501 v = SAL_MAX_ENUM 502 }; 503 504 505 class BinaryCompatible_Impl 506 { 507 public: 508 BinaryCompatible_Impl(); 509 }; 510 BinaryCompatible_Impl::BinaryCompatible_Impl() 511 { 512 BOOST_STATIC_ASSERT( ((sal_Bool) true) == sal_True && 513 (1 != 0) == sal_True ); 514 BOOST_STATIC_ASSERT( ((sal_Bool) false) == sal_False && 515 (1 == 0) == sal_False ); 516 #ifdef MAX_ALIGNMENT_4 517 // max alignment is 4 518 BINTEST_VERIFYOFFSET( AlignSize_Impl, dDouble, 4 ); 519 BINTEST_VERIFYSIZE( AlignSize_Impl, 12 ); 520 #else 521 // max alignment is 8 522 BINTEST_VERIFYOFFSET( AlignSize_Impl, dDouble, 8 ); 523 BINTEST_VERIFYSIZE( AlignSize_Impl, 16 ); 524 #endif 525 526 // sequence 527 BINTEST_VERIFY( (SAL_SEQUENCE_HEADER_SIZE % 8) == 0 ); 528 // enum 529 BINTEST_VERIFY( sizeof( Enum ) == sizeof( sal_Int32 ) ); 530 // any 531 BINTEST_VERIFY( sizeof(void *) >= sizeof(sal_Int32) ); 532 BINTEST_VERIFY( sizeof( uno_Any ) == sizeof( void * ) * 3 ); 533 BINTEST_VERIFYOFFSET( uno_Any, pType, 0 ); 534 BINTEST_VERIFYOFFSET( uno_Any, pData, 1 * sizeof (void *) ); 535 BINTEST_VERIFYOFFSET( uno_Any, pReserved, 2 * sizeof (void *) ); 536 // interface 537 BINTEST_VERIFY( sizeof( Ref ) == sizeof( void * ) ); 538 // string 539 BINTEST_VERIFY( sizeof( OUString ) == sizeof( rtl_uString * ) ); 540 // struct 541 BINTEST_VERIFYSIZE( M, 8 ); 542 BINTEST_VERIFYOFFSET( M, o, 4 ); 543 BINTEST_VERIFYSIZE( N, 12 ); 544 BINTEST_VERIFYOFFSET( N, p, 8 ); 545 BINTEST_VERIFYSIZE( N2, 12 ); 546 BINTEST_VERIFYOFFSET( N2, p, 8 ); 547 #ifdef MAX_ALIGNMENT_4 548 BINTEST_VERIFYSIZE( O, 20 ); 549 #else 550 BINTEST_VERIFYSIZE( O, 24 ); 551 #endif 552 BINTEST_VERIFYSIZE( D, 8 ); 553 BINTEST_VERIFYOFFSET( D, e, 4 ); 554 BINTEST_VERIFYOFFSET( E, d, 4 ); 555 BINTEST_VERIFYOFFSET( E, e, 8 ); 556 557 BINTEST_VERIFYSIZE( C1, 2 ); 558 BINTEST_VERIFYSIZE( C2, 8 ); 559 BINTEST_VERIFYOFFSET( C2, n2, 4 ); 560 561 #ifdef MAX_ALIGNMENT_4 562 BINTEST_VERIFYSIZE( C3, 20 ); 563 BINTEST_VERIFYOFFSET( C3, d3, 8 ); 564 BINTEST_VERIFYOFFSET( C3, n3, 16 ); 565 BINTEST_VERIFYSIZE( C4, 32 ); 566 BINTEST_VERIFYOFFSET( C4, n4, 20 ); 567 BINTEST_VERIFYOFFSET( C4, d4, 24 ); 568 BINTEST_VERIFYSIZE( C5, 44 ); 569 BINTEST_VERIFYOFFSET( C5, n5, 32 ); 570 BINTEST_VERIFYOFFSET( C5, b5, 40 ); 571 BINTEST_VERIFYSIZE( C6, 52 ); 572 BINTEST_VERIFYOFFSET( C6, c6, 4 ); 573 BINTEST_VERIFYOFFSET( C6, b6, 48 ); 574 575 BINTEST_VERIFYSIZE( O2, 24 ); 576 BINTEST_VERIFYOFFSET( O2, p2, 20 ); 577 #else 578 BINTEST_VERIFYSIZE( C3, 24 ); 579 BINTEST_VERIFYOFFSET( C3, d3, 8 ); 580 BINTEST_VERIFYOFFSET( C3, n3, 16 ); 581 BINTEST_VERIFYSIZE( C4, 40 ); 582 BINTEST_VERIFYOFFSET( C4, n4, 24 ); 583 BINTEST_VERIFYOFFSET( C4, d4, 32 ); 584 BINTEST_VERIFYSIZE( C5, 56 ); 585 BINTEST_VERIFYOFFSET( C5, n5, 40 ); 586 BINTEST_VERIFYOFFSET( C5, b5, 48 ); 587 BINTEST_VERIFYSIZE( C6, 72 ); 588 BINTEST_VERIFYOFFSET( C6, c6, 8 ); 589 BINTEST_VERIFYOFFSET( C6, b6, 64 ); 590 591 BINTEST_VERIFYSIZE( O2, 32 ); 592 BINTEST_VERIFYOFFSET( O2, p2, 24 ); 593 #endif 594 595 BINTEST_VERIFYSIZE( Char3, 3 ); 596 BINTEST_VERIFYOFFSET( Char4, c, 3 ); 597 598 #ifdef MAX_ALIGNMENT_4 599 // max alignment is 4 600 BINTEST_VERIFYSIZE( P, 20 ); 601 #else 602 // alignment of P is 8, because of P[] ... 603 BINTEST_VERIFYSIZE( P, 24 ); 604 BINTEST_VERIFYSIZE( second, sizeof( int ) ); 605 #endif 606 } 607 608 #ifdef SAL_W32 609 # pragma pack(pop) 610 #elif defined(SAL_OS2) 611 # pragma pack() 612 #endif 613 614 static BinaryCompatible_Impl aTest; 615 616 #endif 617 618 } 619