2010-12-08 24 views
7

Từ C++ 2003 2,13xung đột: định nghĩa của chuỗi wchar_t trong C + + tiêu chuẩn và thực hiện Windows?

Một chuỗi rộng theo nghĩa đen có kiểu “mảng n const wchar_t” và có thời gian lưu trữ tĩnh, trong đó n là kích thước của chuỗi theo quy định dưới đây

Kích thước của một chuỗi chữ lớn là tổng số chuỗi thoát, tên ký tự phổ quát, và các ký tự khác, cộng với một cho kết thúc L '\ 0'.

Từ C++ 0x 2.14.5

Một chuỗi rộng theo nghĩa đen có kiểu “mảng n const wchar_t”, trong đó n là kích thước của chuỗi theo quy định dưới đây

Các kích thước của một char32_t hoặc chuỗi chữ lớn là tổng số chuỗi thoát, tên ký tự phổ quát, và các ký tự khác, cộng với một cho kết thúc U '\ 0' hoặc L '\ 0'.

Kích thước của chuỗi chữ char16_t là tổng số chuỗi thoát, tên ký tự phổ quát và các ký tự khác, cộng với một ký tự cho mỗi ký tự yêu cầu cặp thay thế, cộng với một ký tự kết thúc u ’\ 0’.

Tuyên bố trong C++ 2003 khá mơ hồ. Nhưng trong C++ 0x, khi đếm chiều dài của chuỗi, chuỗi ký tự bằng chữ thường sẽ được xử lý giống như char32_t, và khác với char16_t.

Có một bài mà nêu rõ cách cửa sổ thực hiện wchar_t trong https://stackoverflow.com/questions/402283?tab=votes%23tab-top

Nói tóm lại, wchar_t trong cửa sổ là 16bits và mã hóa sử dụng UTF-16. Các tuyên bố trong tiêu chuẩn rõ ràng để lại một cái gì đó xung đột trong Windows.

ví dụ,

wchar_t kk[] = L"\U000E0005"; 

này vượt 16bits và UTF-16 nó cần hai 16 bit để mã hóa nó (một cặp thay thế).

Tuy nhiên, từ tiêu chuẩn, kk là một mảng 2 wchar_t (1 cho tên phổ quát \ U000E005, 1 cho \ 0).

Nhưng trong bộ nhớ trong, Windows cần 3 đối tượng wchar_t 16 bit để lưu trữ nó, 2 wchar_t cho cặp thay thế và 1 wchar_t cho \ 0. Vì vậy, từ định nghĩa của mảng, kk là một mảng của 3 wchar_t.

Có vẻ như mâu thuẫn với nhau.

Tôi nghĩ rằng một giải pháp đơn giản nhất cho Windows là "cấm" bất cứ thứ gì yêu cầu cặp thay thế trong wchar_t ("cấm" bất kỳ unicode nào bên ngoài BMP).

Có điều gì sai với hiểu biết của tôi không?

Cảm ơn.

Trả lời

3

Tiêu chuẩn yêu cầu wchar_t đủ lớn để giữ bất kỳ ký tự nào trong bộ ký tự được hỗ trợ.Dựa trên điều này, tôi nghĩ rằng tiền đề của bạn là chính xác - nó là sai cho VC + + để đại diện cho các ký tự đơn \U000E0005 sử dụng hai đơn vị wchar_t.

Ký tự bên ngoài BMP hiếm khi được sử dụng và bản thân Windows sử dụng mã UTF-16, vì vậy nó chỉ đơn giản là thuận tiện (ngay cả khi không chính xác) cho VC++ hoạt động theo cách này. Tuy nhiên, thay vì "cấm" các ký tự như vậy, có khả năng kích thước của wchar_t sẽ tăng trong tương lai trong khi char16_t diễn ra trong API Windows.

Câu trả lời bạn liên quan đến có phần sai lệch cũng như:

Trên Linux, một wchar_t là 4-byte, trong khi trên Windows, đó là 2-byte

Kích thước của wchar_t phụ thuộc chỉ trên trình biên dịch và không liên quan gì đến hệ điều hành. Nó chỉ xảy ra rằng VC++ sử dụng 2 byte cho wchar_t, nhưng một lần nữa, điều này có thể thay đổi rất tốt trong tương lai.

+0

cảm ơn bạn. tôi hiểu rồi. đôi khi thật khó để hiểu một khái niệm mới, nhưng một khi bạn đã có nó, nó trở nên đơn giản ngay lập tức. – user534498

+0

Windows sử dụng kỹ thuật 'WCHAR', không phải' wchar_t'. Nó được đánh máy là "unsigned short' trong quá khứ và có thể trở thành' char16_t' trong tương lai. Nhưng thành thật mà nói, tôi không thấy điều đó xảy ra - các chuỗi ký tự sẽ phá vỡ. – MSalters

+0

@MSalters: Tại sao chuỗi ký tự bị đứt? Đó là những gì các macro 'TEXT (" ... ")' có cho - mọi người không bao giờ được phép sử dụng nguyên 'L" ... "' chữ. Ngoài ra, ít nhất là trên VS2005, 'WCHAR' là một typedef cho' wchar_t', không phải là 'unsigned short'. – casablanca

1

Windows không biết gì về wchar_t, vì wchar_t là một khái niệm lập trình. Ngược lại, wchar_t chỉ là lưu trữ và không biết gì về giá trị ngữ nghĩa của dữ liệu mà bạn lưu trữ trong đó (nghĩa là nó không biết gì về Unicode hoặc ASCII hoặc bất kỳ thứ gì.)

Nếu trình biên dịch hoặc SDK nhắm vào Windows xác định wchar_t là 16 bit, trình biên dịch đó có thể xung đột với chuẩn C++ 0x. (Tôi không biết liệu có một số mệnh đề cho phép wchar_t là 16 bit không.) Nhưng trong mọi trường hợp, trình biên dịch có thể định nghĩa wchar_t là 32 bit (tuân theo chuẩn) và cung cấp các hàm thời gian chạy để chuyển đổi thành/từ UTF-16 khi bạn cần chuyển wchar_t * sang Windows API.

Các vấn đề liên quan