MSVC compatibility — Clang 20.0.0git documentation (2024)

When Clang compiles C++ code for Windows, it attempts to be compatible withMSVC. There are multiple dimensions to compatibility.

First, Clang attempts to be ABI-compatible, meaning that Clang-compiled codeshould be able to link against MSVC-compiled code successfully. However, C++ABIs are particularly large and complicated, and Clang’s support for MSVC’s C++ABI is a work in progress. If you don’t require MSVC ABI compatibility or don’twant to use Microsoft’s C and C++ runtimes, the mingw32 toolchain might be abetter fit for your project.

Second, Clang implements many MSVC language extensions, such as__declspec(dllexport) and a handful of pragmas. These are typicallycontrolled by -fms-extensions.

Third, MSVC accepts some C++ code that Clang will typically diagnose asinvalid. When these constructs are present in widely included system headers,Clang attempts to recover and continue compiling the user’s program. Mostparsing and semantic compatibility tweaks are controlled by-fms-compatibility and -fdelayed-template-parsing, and they are a workin progress.

Finally, there is clang-cl, a driver program for clang that attempts tobe compatible with MSVC’s cl.exe.

ABI features

The status of major ABI-impacting C++ features:

  • Record layout: Complete. We’ve tested this with a fuzzer and havefixed all known bugs.

  • Class inheritance: Mostly complete. This covers all of the standardOO features you would expect: virtual method inheritance, multipleinheritance, and virtual inheritance. Every so often we uncover a bug whereour tables are incompatible, but this is pretty well in hand. This featurehas also been fuzz tested.

  • Name mangling: Ongoing. Every new C++ feature generally needs its ownmangling. For example, member pointer template arguments have an interestingand distinct mangling. Fortunately, incorrect manglings usually do not resultin runtime errors. Non-inline functions with incorrect manglings usuallyresult in link errors, which are relatively easy to diagnose. Incorrectmanglings for inline functions and templates result in multiple copies in thefinal image. The C++ standard requires that those addresses be equal, but fewprograms rely on this.

  • Member pointers: Mostly complete. Standard C++ member pointers arefully implemented and should be ABI compatible. Both #pragmapointers_to_members and the /vm flags are supported. However, MSVCsupports an extension to allow creating a pointer to a member of a virtualbase class. Clang does not yet support this.

  • Debug info: Mostly complete. Clang emits relatively complete CodeViewdebug information if /Z7 or /Zi is passed. Microsoft’s link.exe willtransform the CodeView debug information into a PDB that works in Windowsdebuggers and other tools that consume PDB files like ETW. Work to teach lldabout CodeView and PDBs is ongoing.

  • RTTI: Complete. Generation of RTTI data structures has beenfinished, along with support for the /GR flag.

  • C++ Exceptions: Mostly complete. Support forC++ exceptions (try / catch / throw) have been implemented forx86 and x64. Our implementation has been well tested but we still get theodd bug report now and again.C++ exception specifications are ignored, but this is consistent with VisualC++.

Template instantiation and name lookup

MSVC allows many invalid constructs in class templates that Clang hashistorically rejected. In order to parse widely distributed headers forlibraries such as the Active Template Library (ATL) and Windows Runtime Library(WRL), some template rules have been relaxed or extended in Clang on Windows.

The first major semantic difference is that MSVC appears to defer all parsingan analysis of inline method bodies in class templates until instantiationtime. By default on Windows, Clang attempts to follow suit. This behavior iscontrolled by the -fdelayed-template-parsing flag. While Clang delaysparsing of method bodies, it still parses the bodies before template argumentsubstitution, which is not what MSVC does. The following compatibility tweaksare necessary to parse the template in those cases.

MSVC allows some name lookup into dependent base classes. Even on otherplatforms, this has been a frequently asked question for Clang users. Adependent base class is a base class that depends on the value of a templateparameter. Clang cannot see any of the names inside dependent bases while itis parsing your template, so the user is sometimes required to use thetypename keyword to assist the parser. On Windows, Clang attempts tofollow the normal lookup rules, but if lookup fails, it will assume that theuser intended to find the name in a dependent base. While parsing thefollowing program, Clang will recover as if the user had written thecommented-out code:

template <typename T>struct Foo : T { void f() { /*typename*/ T::UnknownType x = /*this->*/unknownMember; }};

After recovery, Clang warns the user that this code is non-standard and issuesa hint suggesting how to fix the problem.

As of this writing, Clang is able to compile a simple ATL hello worldapplication. There are still issues parsing WRL headers for modern Windows 8apps, but they should be addressed soon.

__forceinline behavior

__forceinline behaves like [[clang::always_inline]].Inlining is always attempted regardless of optimization level.

This differs from MSVC where __forceinline is only respected once inline expansion is enabledwhich allows any function marked implicitly or explicitly inline or __forceinline to be expanded.Therefore functions marked __forceinline will be expanded when the optimization level is /Od unlikeMSVC where __forceinline will not be expanded under /Od.

SIMD and instruction set intrinsic behavior

Clang follows the GCC model for intrinsics and not the MSVC model.There are currently no plans to support the MSVC model.

MSVC intrinsics always emit the machine instruction the intrinsic models regardless of the compile time options specified.For example __popcnt always emits the x86 popcnt instruction even if the compiler does not have the option enabled to emit popcnt on its own volition.

There are two common cases where code that compiles with MSVC will need reworking to build on clang.Assume the examples are only built with -msse2 so we do not have the intrinsics at compile time.

unsigned PopCnt(unsigned v) { if (HavePopCnt) return __popcnt(v); else return GenericPopCnt(v);}
__m128 dot4_sse3(__m128 v0, __m128 v1) { __m128 r = _mm_mul_ps(v0, v1); r = _mm_hadd_ps(r, r); r = _mm_hadd_ps(r, r); return r;}

Clang expects that either you have compile time support for the target features, -msse3 and -mpopcnt, you mark the function with the expected target feature or use runtime detection with an indirect call.

__attribute__((__target__("sse3"))) __m128 dot4_sse3(__m128 v0, __m128 v1) { __m128 r = _mm_mul_ps(v0, v1); r = _mm_hadd_ps(r, r); r = _mm_hadd_ps(r, r); return r;}

The SSE3 dot product can be easily fixed by either building the translation unit with SSE3 support or using __target__ to compile that specific function with SSE3 support.

unsigned PopCnt(unsigned v) { if (HavePopCnt) return __popcnt(v); else return GenericPopCnt(v);}

The above PopCnt example must be changed to work with clang. If we mark the function with __target__(“popcnt”) then the compiler is free to emit popcnt at will which we do not want. While this isn’t a concern in our small example it is a concern in larger functions with surrounding code around the intrinsics. Similar reasoning for compiling the translation unit with -mpopcnt.We must split each branch into its own function that can be called indirectly instead of using the intrinsic directly.

__attribute__((__target__("popcnt"))) unsigned hwPopCnt(unsigned v) { return __popcnt(v); }unsigned (*PopCnt)(unsigned) = HavePopCnt ? hwPopCnt : GenericPopCnt;
__attribute__((__target__("popcnt"))) unsigned hwPopCnt(unsigned v) { return __popcnt(v); }unsigned PopCnt(unsigned v) { if (HavePopCnt) return hwPopCnt(v); else return GenericPopCnt(v);}

In the above example hwPopCnt will not be inlined into PopCnt since PopCnt doesn’t have the popcnt target feature.With a larger function that does real work the function call overhead is negligible. However in our popcnt example there is the function calloverhead. There is no analog for this specific MSVC behavior in clang.

For clang we effectively have to create the dispatch function ourselves to each specfic implementation.

SIMD vector types

Clang’s simd vector types are builtin types and not user defined types as in MSVC. This does have some observable behavior changes.We will look at the x86 __m128 type for the examples below but the statements apply to all vector types including ARM’s float32x4_t.

There are no members that can be accessed on the vector types. Vector types are not structs in clang.You cannot use __m128.m128_f32[0] to access the first element of the __m128.This also means struct initialization like __m128{ { 0.0f, 0.0f, 0.0f, 0.0f } } will not compile with clang.

Since vector types are builtin types, clang implements operators on them natively.

#ifdef _MSC_VER__m128 operator+(__m128 a, __m128 b) { return _mm_add_ps(a, b); }#endif

The above code will fail to compile since overloaded ‘operator+’ must have at least one parameter of class or enumeration type.You will need to fix such code to have the check #if defined(_MSC_VER) && !defined(__clang__).

Since __m128 is not a class type in clang any overloads after a template definition will not be considered.

template<class T>void foo(T) {}template<class T>void bar(T t) { foo(t);}void foo(__m128) {}int main() { bar(_mm_setzero_ps());}

With MSVC foo(__m128) will be selected but with clang foo<__m128>() will be selected since on clang __m128 is a builtin type.

In general the takeaway is __m128 is a builtin type on clang while a class type on MSVC.

MSVC compatibility — Clang 20.0.0git documentation (2024)
Top Articles
Why Nvidia is the top chipmaker in AI
Ethics In Private Investigation Principles And Practices - Stillinger Investigations, Inc.
Ups Customer Center Locations
Ups Dropoff Location Near Me
Archived Obituaries
Erika Kullberg Wikipedia
Jonathon Kinchen Net Worth
Free Atm For Emerald Card Near Me
Georgia Vehicle Registration Fees Calculator
Sam's Club Gas Price Hilliard
Obituary (Binghamton Press & Sun-Bulletin): Tully Area Historical Society
Nikki Catsouras Head Cut In Half
Strange World Showtimes Near Amc Braintree 10
Bernie Platt, former Cherry Hill mayor and funeral home magnate, has died at 90
Scholarships | New Mexico State University
6th gen chevy camaro forumCamaro ZL1 Z28 SS LT Camaro forums, news, blog, reviews, wallpapers, pricing – Camaro5.com
Mini Handy 2024: Die besten Mini Smartphones | Purdroid.de
Unlv Mid Semester Classes
979-200-6466
Northeastern Nupath
Watch The Lovely Bones Online Free 123Movies
Morristown Daily Record Obituary
A Person That Creates Movie Basis Figgerits
Nsa Panama City Mwr
Certain Red Dye Nyt Crossword
MyCase Pricing | Start Your 10-Day Free Trial Today
Trivago Myrtle Beach Hotels
Jesus Calling Feb 13
Pokémon Unbound Starters
Select The Best Reagents For The Reaction Below.
Vlacs Maestro Login
My Dog Ate A 5Mg Flexeril
DIY Building Plans for a Picnic Table
Helloid Worthington Login
Why Are The French So Google Feud Answers
3 Bedroom 1 Bath House For Sale
Joplin Pets Craigslist
Why Gas Prices Are So High (Published 2022)
Craigslist Summersville West Virginia
Tokyo Spa Memphis Reviews
B.C. lightkeepers' jobs in jeopardy as coast guard plans to automate 2 stations
Scarlet Maiden F95Zone
Honkai Star Rail Aha Stuffed Toy
Tropical Smoothie Address
855-539-4712
Rite Aid | Employee Benefits | Login / Register | Benefits Account Manager
18 Seriously Good Camping Meals (healthy, easy, minimal prep! )
Definition of WMT
Cars & Trucks near Old Forge, PA - craigslist
Bones And All Showtimes Near Emagine Canton
Latest Posts
Article information

Author: Reed Wilderman

Last Updated:

Views: 6451

Rating: 4.1 / 5 (52 voted)

Reviews: 91% of readers found this page helpful

Author information

Name: Reed Wilderman

Birthday: 1992-06-14

Address: 998 Estell Village, Lake Oscarberg, SD 48713-6877

Phone: +21813267449721

Job: Technology Engineer

Hobby: Swimming, Do it yourself, Beekeeping, Lapidary, Cosplaying, Hiking, Graffiti

Introduction: My name is Reed Wilderman, I am a faithful, bright, lucky, adventurous, lively, rich, vast person who loves writing and wants to share my knowledge and understanding with you.