title: Visual Studio Character Sets 'Not set' vs 'Multi byte character set'
body: <p>I've working with a legacy application and I'm trying to work out the difference between applications compiled with <code>Multi byte character set</code> and <code>Not Set</code> under the <code>Character Set</code> option.</p>
  
  <p>I understand that compiling with <code>Multi byte character set</code> defines <code>_MBCS</code> which allows multi byte character set code pages to be used, and using <code>Not set</code> doesn't define <code>_MBCS</code>, in which case only single byte character set code pages are allowed.</p>
  
  <p>In the case that <code>Not Set</code> is used, I'm assuming then that we can only use the single byte character set code pages found on this page: <a href="http://msdn.microsoft.com/en-gb/goglobal/bb964654.aspx" rel="nofollow noreferrer">http://msdn.microsoft.com/en-gb/goglobal/bb964654.aspx</a></p>
  
  <p>Therefore, am I correct in thinking that is <code>Not Set</code> is used, the application won't be able to encode and write or read far eastern languages since they are defined in double byte character set code pages (and of course Unicode)?</p>
  
  <p>Following on from this, if <code>Multi byte character</code> set is defined, are both single and multi byte character set code pages available, or only multi byte character set code pages? I'm guessing it must be both for European languages to be supported.</p>
  
  <p>Thanks,</p>
  
  <p>Andy</p>
  
  <p><strong>Further Reading</strong></p>
  
  <p>The answers on these pages didn't answer my question, but helped in my understanding:
  <a href="https://stackoverflow.com/questions/9349342/about-the-character-set-option-in-visual-studio-2010">About the &quot;Character set&quot; option in visual studio 2010</a></p>
  
  <p><strong>Research</strong></p>
  
  <p>So, just as working research... With my locale set as Japanese</p>
  
  <p><strong>Effect on hard coded strings</strong></p>
  
  <pre><code>char *foo = "Jap text: テスト";
  wchar_t *bar = L"Jap text: テスト";
  </code></pre>
  
  <p>Compiling with <code>Unicode</code></p>
  
  <blockquote>
    <p>*foo = 4a 61 70 20 74 65 78 74 3a 20 83 65 83 58 83 67 == <a href="http://msdn.microsoft.com/en-gb/goglobal/gg638603" rel="nofollow noreferrer">Shift-Jis (Code page 932)</a><br>
    *bar = 4a 00 61 00 70 00 20 00 74 00 65 00 78 00 74 00 3a 00 20 00 c6 30 b9 30 c8 30 == <a href="http://www.unicodemap.org/details/0x30C6/index.html" rel="nofollow noreferrer">UTF-16 or UCS-2</a></p>
  </blockquote>
  
  <p>Compiling with <code>Multi byte character set</code></p>
  
  <blockquote>
    <p>*foo = 4a 61 70 20 74 65 78 74 3a 20 83 65 83 58 83 67 == <a href="http://msdn.microsoft.com/en-gb/goglobal/gg638603" rel="nofollow noreferrer">Shift-Jis (Code page 932)</a><br>
    *bar = 4a 00 61 00 70 00 20 00 74 00 65 00 78 00 74 00 3a 00 20 00 c6 30 b9 30 c8 30 == <a href="http://www.unicodemap.org/details/0x30C6/index.html" rel="nofollow noreferrer">UTF-16 or UCS-2</a></p>
  </blockquote>
  
  <p>Compiling with <code>Not Set</code></p>
  
  <blockquote>
    <p>*foo = 4a 61 70 20 74 65 78 74 3a 20 83 65 83 58 83 67 == <a href="http://msdn.microsoft.com/en-gb/goglobal/gg638603" rel="nofollow noreferrer">Shift-Jis (Code page 932)</a><br>
    *bar = 4a 00 61 00 70 00 20 00 74 00 65 00 78 00 74 00 3a 00 20 00 c6 30 b9 30 c8 30 == <a href="http://www.unicodemap.org/details/0x30C6/index.html" rel="nofollow noreferrer">UTF-16 or UCS-2</a></p>
  </blockquote>
  
  <p><em>Conclusion:</em>
  The character encoding doesn't have any effect on hard coded strings. Although defining chars as above seems to use the Locale defined codepage and wchar_t seems to use either UCS-2 or UTF-16.</p>
  
  <p><strong>Using encoded strings in W/A versions of Win32 APIs</strong></p>
  
  <p>So, using the following code:</p>
  
  <pre><code>char *foo = "C:\\Temp\\テスト\\テa.txt";
  wchar_t *bar = L"C:\\Temp\\テスト\\テw.txt";
  
  CreateFileA(bar, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  CreateFileW(foo, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  </code></pre>
  
  <p>Compiling with <code>Unicode</code></p>
  
  <p>Result: Both files are created</p>
  
  <p>Compiling with <code>Multi byte character set</code></p>
  
  <p>Result: Both files are created</p>
  
  <p>Compiling with <code>Not set</code></p>
  
  <p>Result: Both files are created</p>
  
  <p><em>Conclusion:</em> 
  Both the <code>A</code> and <code>W</code> version of the API expect the same encoding regardless of the character set chosen. From this, perhaps we can assume that all the <code>Character Set</code> option does is switch between the version of the API. So the <code>A</code> version always expects strings in the encoding of the current code page and the <code>W</code> version always expects UTF-16 or UCS-2.</p>
  
  <p><strong>Opening files using W and A Win32 APIs</strong></p>
  
  <p>So using the following code:</p>
  
  <pre><code>char filea[MAX_PATH] = {0};
  OPENFILENAMEA ofna = {0};
  ofna.lStructSize = sizeof ( ofna );
  ofna.hwndOwner = NULL  ;
  ofna.lpstrFile = filea ;
  ofna.nMaxFile = MAX_PATH;
  ofna.lpstrFilter = "All\0*.*\0Text\0*.TXT\0";
  ofna.nFilterIndex =1;
  ofna.lpstrFileTitle = NULL ;
  ofna.nMaxFileTitle = 0 ;
  ofna.lpstrInitialDir=NULL ;
  ofna.Flags = OFN_PATHMUSTEXIST|OFN_FILEMUSTEXIST ;  
  
  wchar_t filew[MAX_PATH] = {0};
  OPENFILENAMEW ofnw = {0};
  ofnw.lStructSize = sizeof ( ofnw );
  ofnw.hwndOwner = NULL  ;
  ofnw.lpstrFile = filew ;
  ofnw.nMaxFile = MAX_PATH;
  ofnw.lpstrFilter = L"All\0*.*\0Text\0*.TXT\0";
  ofnw.nFilterIndex =1;
  ofnw.lpstrFileTitle = NULL;
  ofnw.nMaxFileTitle = 0 ;
  ofnw.lpstrInitialDir=NULL ;
  ofnw.Flags = OFN_PATHMUSTEXIST|OFN_FILEMUSTEXIST ;
  
  GetOpenFileNameA(&amp;ofna);
  GetOpenFileNameW(&amp;ofnw);
  </code></pre>
  
  <p>and selecting either:</p>
  
  <ul>
  <li>C:\Temp\テスト\テopenw.txt</li>
  <li>C:\Temp\テスト\テopenw.txt</li>
  </ul>
  
  <p>Yields:</p>
  
  <p>When compiled with <code>Unicode</code></p>
  
  <blockquote>
    <p>*filea = 43 3a 5c 54 65 6d 70 5c 83 65 83 58 83 67 5c 83 65 6f 70 65 6e 61 2e 74 78 74 == <a href="http://msdn.microsoft.com/en-gb/goglobal/gg638603" rel="nofollow noreferrer">Shift-Jis (Code page 932)</a><br>
    *filew = 43 00 3a 00 5c 00 54 00 65 00 6d 00 70 00 5c 00 c6 30 b9 30 c8 30 5c 00 c6 30 6f 00 70 00 65 00 6e 00 77 00 2e 00 74 00 78 00 74
    00 == <a href="http://www.unicodemap.org/details/0x30C6/index.html" rel="nofollow noreferrer">UTF-16 or UCS-2</a></p>
  </blockquote>
  
  <p>When compiled with <code>Multi byte character set</code></p>
  
  <blockquote>
    <p>*filea = 43 3a 5c 54 65 6d 70 5c 83 65 83 58 83 67 5c 83 65 6f 70 65 6e 61 2e 74 78 74 == <a href="http://msdn.microsoft.com/en-gb/goglobal/gg638603" rel="nofollow noreferrer">Shift-Jis (Code page 932)</a><br>
    *filew = 43 00 3a 00 5c 00 54 00 65 00 6d 00 70 00 5c 00 c6 30 b9 30 c8 30 5c 00 c6 30 6f 00 70 00 65 00 6e 00 77 00 2e 00 74 00 78 00 74
    00 == <a href="http://www.unicodemap.org/details/0x30C6/index.html" rel="nofollow noreferrer">UTF-16 or UCS-2</a></p>
  </blockquote>
  
  <p>When compiled with <code>Not Set</code></p>
  
  <blockquote>
    <p>*filea = 43 3a 5c 54 65 6d 70 5c 83 65 83 58 83 67 5c 83 65 6f 70 65 6e 61 2e 74 78 74 == <a href="http://msdn.microsoft.com/en-gb/goglobal/gg638603" rel="nofollow noreferrer">Shift-Jis (Code page 932)</a><br>
    *filew = 43 00 3a 00 5c 00 54 00 65 00 6d 00 70 00 5c 00 c6 30 b9 30 c8 30 5c 00 c6 30 6f 00 70 00 65 00 6e 00 77 00 2e 00 74 00 78 00 74
    00 == <a href="http://www.unicodemap.org/details/0x30C6/index.html" rel="nofollow noreferrer">UTF-16 or UCS-2</a></p>
  </blockquote>
  
  <p><em>Conclusion:</em>
  Again, the <code>Character Set</code> setting doesn't have a bearing on the behaviour of the Win32 API. The <code>A</code> version always seems to return a string with the encoding of the active code page and the <code>W</code> one always returns UTF-16 or UCS-2. I can actually see this explained a bit in this great answer: <a href="https://stackoverflow.com/a/3299860/187100">https://stackoverflow.com/a/3299860/187100</a>.</p>
  
  <p><strong>Ultimate Conculsion</strong></p>
  
  <p>Hans appears to be correct when he says that the define doesn't really have any magic to it, beyond changing the Win32 APIs to use either <code>W</code> or <code>A</code>. Therefore, I can't really see any difference between <code>Not Set</code> and <code>Multi byte character set</code>.</p>