User666
User666

Reputation: 131

warning C4090: 'initializing': different '__unaligned' qualifiers

 void file_explore(std::wstring str) {
     ITEMIDLIST *pIDL = ILCreateFromPath(str.c_str());
     if ( NULL != pIDL ) {
         SHOpenFolderAndSelectItems(pIDL , 0 , 0 , 0);
         ILFree(pIDL);
     } else {
         std::wstring p = str.substr(0 , str.find_last_of('\\'));
         ShellExecute(NULL , L"explore" , p.c_str() , NULL , NULL , SW_SHOWNORMAL);
     }
 }    

The above compiles without warning for 32bit but with 64bit I get warning c4090 however the docs: https://msdn.microsoft.com/en-us/library/k77bkb8d.aspx state that this is a c error and I will get C2440 for c++ yet I'm using c++.

The line of code complained of is:

 ITEMIDLIST *pIDL = ILCreateFromPath(str.c_str());

How to fix this issue for 64bit builds?

Upvotes: 2

Views: 1728

Answers (2)

Andry
Andry

Reputation: 2727

I have had a similar issue while been declared _X86_ macro definition instead of _AMD64_.

Upvotes: 0

McMustard
McMustard

Reputation: 169

LPITEMIDLIST is defined as typedef ITEMIDLIST __unaligned *LPITEMIDLIST, so accepting the result as ITEMIDLIST * loses that __unaligned modifier. I am not sure how this relates to 32-bit versus 64-bit.

As Hans Passant commented, using the typedef solves the issue. In my case, I'm using std::unique_ptr, which wants the base type rather than the pointer, so I needed a non-pointer typedef. Because it might be of tangential interest for people stumbling upon this answer, I'll put in how I am making use of a std::unique_ptr with ILCreateFromPath, including the custom deleter for fun:

auto deleter = [](LPITEMIDLIST ptr) { ILFree(ptr); };
using itemidlistptr_t = std::unique_ptr<
    std::remove_ptr_t<LPITEMIDLIST>, decltype(deleter)>;
auto dir = itemidlistptr_t(ILCreateFromPathW(folder.c_str()), deleter);

Using std::remove_pointer_t is a bit roundabout, but I like it here rather than mentioning __unaligned myself directly.

Upvotes: 6

Related Questions