2013-01-23 25 views
8

Tôi có một biến địa phương theo chủ đề envptr và biến không phải là luồng-địa phương cũng được gọi là envptr. Biến thứ hai chỉ được sử dụng trong một chuỗi duy nhất có mã chạy không thấy khai báo biến cục bộ. Biến thread-local được sử dụng bởi các luồng khác nhau, mỗi luồng không nhìn thấy và cũng không cần phải nhìn thấy khai báo của biến không-chủ-cục bộ.Có OK để có biến chủ đề cục bộ có cùng tên với biến không phải là chủ đề cục bộ không?

Kịch bản này có thể và tạo ra hành vi được xác định không? Tôi đang sử dụng Linux 32bit và 64bit trên x86.

+0

Có mã ví dụ về cách một 'envptr' sẽ được trang trí bằng' __thread' (?), Nhưng khác thì không? Cách duy nhất tôi có thể tưởng tượng đây là không phải là externs trong hai tập tin khác nhau ..và nếu có, thì có vẻ như nó có thể là câu trả lời đơn giản trong ngữ cảnh đó. –

+1

@pst có, đó là cách thực hiện. chúng được khai báo trong các tệp cpp và một hàm 'Env * getEnv();' được cung cấp trong một tiêu đề. Mỗi tệp '.cpp' định nghĩa nó khác nhau. Các chủ đề sử dụng phiên bản TLS chạy trên mã từ một tệp '.so' được nạp vào cùng một tiến trình như luồng chính sử dụng biến không TLS (là trình biên dịch LLVM JIT được sử dụng bởi một trình bao REPl). –

+0

Tôi đã bỏ phiếu để đóng vì tôi nghĩ rằng nó có một giải pháp thực sự đơn giản: Tôi sẽ chỉ sử dụng một tên khác cho tệp .cpp được liên kết với tệp DLL và tệp .cpp được liên kết với tệp thực thi chính. EDIT: Điều này sẽ hạn chế khả năng áp dụng của các tập tin .so, vì vậy tôi vẫn muốn thử các cách tiếp cận khác. –

Trả lời

3

Chúng có cùng biến hay không? Nói cách khác, linkage của họ là gì?

Nếu nó ở bên ngoài, thì không. Nếu nó là nội bộ, sau đó nó là OK trừ khi hai định nghĩa cả hai xảy ra trong cùng một tệp.

Nếu không có liên kết, thì không có vấn đề gì.

Trừ khi tôi bỏ qua điều gì đó, thread_local không ảnh hưởng đến liên kết, vì vậy quy tắc thông thường sẽ áp dụng (và xác định biến thread_local trong một đơn vị dịch và không vi phạm quy tắc một định nghĩa).

Tôi nghĩ rằng có một lỗi trong tiêu chuẩn ở đây, tuy nhiên. Các tiêu chuẩn (§7.1.1/1) nói rằng "Nếu thread_local xuất hiện trong bất kỳ tuyên bố nào của một biến, nó sẽ có mặt trong tất cả các khai báo của thực thể đó." Không có tuyên bố rõ ràng rằng không cần chẩn đoán hoặc vi phạm quy tắc này là hành vi không xác định, vì vậy trình biên dịch là yêu cầu để chẩn đoán lỗi. Ngoại trừ việc, tất nhiên, nếu bạn định nghĩa ở phạm vi namespace:

thread_local int i; 

trong một đơn vị dịch thuật và:

int i; 

trong khác, sau đó trình biên dịch có lẽ không thể chẩn đoán lỗi (và tôi khá chắc chắn ủy ban không muốn yêu cầu nó). Tôi đoán là ý định ở đây là hành vi không xác định.

+1

Có, biến là bên ngoài, vì vậy rất tiếc ý tưởng của tôi sẽ không hoạt động. Tôi sẽ thử các cách tiếp cận khác sau đó. –

3

Điều này sẽ hoạt động và tạo ra hành vi đúng, vì các biến là hai biến riêng biệt.

Tôi thực sự khuyên bạn không nên làm điều này vì nó sẽ làm cho phần mềm ít bảo trì hơn. Có hay không hành vi này là chính xác có vẻ ít quan trọng như cách dễ hiểu mã sẽ được - sử dụng cùng một tên biến cho hai bộ dữ liệu với hành vi rất khác nhau có vẻ như có vấn đề.

+0

@pst có rất nhiều mã được xác định rõ ràng không phải là "OK". – Yakk

+0

@Yakk Tác giả đã sử dụng "OK" (mà tôi đưa vào dấu ngoặc kép) để tham khảo câu hỏi: "Kịch bản này có thể và tạo ra hành vi được xác định không?" –

+0

Tôi đồng ý rằng "có thể và tạo ra hành vi được xác định". :) Nhưng tôi khuyên bạn nên tránh việc có các biến toàn cầu (và thread-local) được đặt tên giống như các biến cục bộ - tôi sẽ đề nghị chọn một lược đồ đặt tên. Hoặc thậm chí chỉ, theo quy ước, gắn nó vào một 'không gian tên thread_local' hoặc bất cứ điều gì. – Yakk

3

Từ mô tả của bạn, có vẻ như chúng là hai biến riêng biệt (không bao giờ là một biến khác) trong trường hợp này có vẻ như ok hoàn toàn từ quan điểm kỹ thuật.

Điều đó nói rằng tôi sẽ không bao giờ đề nghị làm điều này vì điều có thể xảy ra nhất là ai đó sẽ bị lẫn lộn về ý nghĩa trong việc bảo trì trong tương lai và sẽ gây ra nhiều vấn đề hơn khi cố gắng hiểu mã.

+1

Cho dù chúng là hai biến riêng biệt hay không phụ thuộc vào liên kết của tên (mà không bị ảnh hưởng bởi 'thread_local'). –