2017-01-04 12 views
6

Visual C++ 2015'in burada bir hata olduğundan eminim, ancak% 100 emin değilim.Dize değişmez birleştirme için doğru davranış (çeviri C++ 11 aşama 6)

Kodu: ++ g ile

// Encoding: UTF-8 with BOM (required by Visual C++). 
#include <stdlib.h> 

auto main() 
    -> int 
{ 
    auto const s = L"" 
     " is not in the Unicode BMP!"; 
    return s[0] > 256? EXIT_SUCCESS : EXIT_FAILURE; 
} 

Sonuç: Visual C++ ile

 
[H:\scratchpad\simple_text_io] 
> g++ --version | find "++" 
g++ (i686-win32-dwarf-rev1, Built by MinGW-W64 project) 6.2.0 

[H:\scratchpad\simple_text_io] 
> g++ compiler_bug_demo.cpp 

[H:\scratchpad\simple_text_io] 
> run a 
Process exit code = 0. 

[H:\scratchpad\simple_text_io] 
> _ 

Sonuç:

 
[H:\scratchpad\simple_text_io] 
> cl /nologo- 2>&1 | find "++" 
Microsoft (R) C/C++ Optimizing Compiler Version 19.00.23026 for x86 

[H:\scratchpad\simple_text_io] 
> cl compiler_bug_demo.cpp /Feb 
compiler_bug_demo.cpp 
compiler_bug_demo.cpp(8): warning C4566: character represented by universal-character-name '\U00010437' cannot be represented in the current code page (1252) 

[H:\scratchpad\simple_text_io] 
> run b 
Process exit code = 1. 

[H:\scratchpad\simple_text_io] 
> _ 

herhangi UB katılan var mı, ve değilse, derleyici doğru davranacağı ?

Zeyilname: bunun bir önemi görünmüyor böylece , BMP içinde olduğunu

küçük Yunan PI kullanırsanız davranış hem derleyiciler için değişmez, π ” “. [lex.string] kaynaktan

+0

"VC++ yanlıştır çünkü §2.14.5, madde 13" derken, karakter kümesini çevreleyen kurallar beni şaşırtıyor. – molbdnilo

+0

VS 2015 güncelleştirmesi 3 ('Microsoft (R) C/C++ Derleyici Sürüm 19.00.24213.1 x86' için en iyi duruma getirme) bunu hiçbir hata veya uyarı olmadan derler; Dosyayı Emacs'de "utf-8-unix" kodlama sisteminde kaydettim. VS'nin hangi sürümüne sahipsin? – legends2k

+0

@ legends2k: Sorudaki örnek, sürümü listeler. –

cevap

1

:

    için faz 6,
  1. bitişik dize hazır birleştirilir. Her iki dize değişmezi de aynı kodlama-önekine sahipse, sonuçta elde edilen birleştirilmiş dize değişmezi bu kodlama-önekine sahiptir. Bir dize değişmezi, kodlama-öneki içermiyorsa, diğer işlenenle aynı kodlama-öneki bir dizgi değişmezi olarak ele alınır. Bir UTF-8 dize değişmez jetonu, geniş bir dize değişmez jetonuna bitişikse, program hatalı biçimlendirilir. Diğer birleştirmeleri, uygulama tarafından tanımlanan davranışlarla koşullu olarak desteklenir. [Not: Bu birleştirme, bir dönüşüm değil, bir yorumdur. Yorum çevirim fazında (6) gerçekleştiği için ( 'dan sonra, her bir karakter, bir karakter dizisinden uygun karakter kümesinden bir değere çevrilmiştir), bir dizgi değişmezinin başlangıçtaki kabadayışının, birleştirme işleminin yorumu veya iyi biçimliliği üzerinde hiçbir etkisi yoktur. —end not] Tablo 8'de bazı geçerli birleştirmeler örnekleri vardır.

    1. Her kaynak karakter kümesi:

    Yani çeviri zaten bazı karakterlerin değerleri değişmiş olabilir ancak, burada faz 5 hayır UB yoktur karakter değişkeni veya dize değişmezi öğesindeki öğesinin yanı sıra, bir karakter değişmezindeki veya bir ham olmayan dize değişmezindeki tüm çıkış dizisi ve evrensel karakter adı, korelasyona dönüştürülen Yürütme karakter kümesinin üyesi olan üye, karşılık gelen üye yoksa, null (geniş) karakterden başka bir uygulama tanımlı üye dönüştürülür.

+0

Evet, faz 5 olayı bana açık değil. Bu zamana kadar, tüm temel kaynak karakter kümesi karakterleri (etkin) Unicode'a çevrildi, ancak "temel karakter kümesi" içinde olmayan "kaynak karakter seti" karakterleri bırakılabilir mi? G ++ ve Visual C++ arasındaki bir fark, Visual C++, Windows ANSI (benim durumumda 1252) için varsayılan olarak iken, g ++, yürütme karakter kümesi olarak UTF-8 varsayılanıdır. Ama böyle bir çeviri genel olarak geniş dize hazırlıkları ile hasara yol açabilir! –

+0

@ Cheersandhth-Alf Muhtemelen uygulamalarını desteklemedikleri ve neleri engellemedikleri konusunda kasıtlı olarak muğlaktır. Örneğin, BMP'den olmayan karakterleri yok saymak için 16 bit geniş karakterli bir derleyiciniz olabilir. (burada olan şey olabilir) –