Từ khóa tĩnh không còn nữa… không còn nữa?


89

Trong C ++, có thể sử dụng statictừ khóa trong một đơn vị dịch để ảnh hưởng đến khả năng hiển thị của một biểu tượng (khai báo biến hoặc hàm).

Trong n3092, tính năng này không được dùng nữa:

Phụ lục D.2 [depr.static]
Việc sử dụng từ khóa static không được chấp nhận khi khai báo các đối tượng trong phạm vi không gian tên (xem 3.3.6).

Trong n3225, điều này đã bị loại bỏ.

Các bài viết duy nhất tôi có thể tìm thấy có phần không chính thức.

Tuy nhiên, nó nhấn mạnh rằng để tương thích với C (và khả năng biên dịch các chương trình C thành C ++), việc không dùng nữa thật khó chịu. Tuy nhiên, việc biên dịch một chương trình C trực tiếp dưới dạng C ++ có thể là một trải nghiệm khó chịu, vì vậy tôi không chắc liệu nó có đảm bảo được sự cân nhắc hay không.

Có ai biết tại sao nó đã được thay đổi?


3
Bạn khai báo các đối tượng ở phạm vi không gian tên trong C?
Etienne de Martel

heh, thx, tìm thấy nơi để nắm giữ nó tại. Đã cố gắng xóa bình luận nhưng bạn đã đánh bại tôi ở đó.
Edward Strange


1
Điều này cũng mang lại cho Ủy ban C ++ cơ hội để unundeprecate một cái gì đó trong phiên bản tiếp theo của chỉ số Standard :-)
James McNellis

Câu trả lời:


75

Trong Báo cáo lỗi ngôn ngữ cốt lõi chuẩn C ++ và các vấn đề được chấp nhận, Bản sửa đổi 94 theo 1012. Tĩnh không phản hồi `họ lưu ý:

Mặc dù 7.3.1.1 [namespace.unname] tuyên bố rằng việc sử dụng từ khóa static để khai báo các biến trong phạm vi không gian tên không được chấp nhận vì không gian tên không có tên cung cấp một giải pháp thay thế vượt trội, nhưng không chắc rằng tính năng này sẽ bị xóa vào bất kỳ thời điểm nào trong tương lai gần. .

Về cơ bản nói rằng việc ngừng sử dụng statickhông thực sự có ý nghĩa. Nó sẽ không bao giờ bị xóa khỏi C ++ và nó vẫn hữu ích vì bạn không cần mã soạn sẵn mà bạn cần với các không gian tên chưa được đặt tên, nếu bạn chỉ muốn khai báo một hàm hoặc đối tượng có liên kết nội bộ.


2
Chà, có vẻ như việc không dùng nữa sẽ khuyến khích mọi người sử dụng không gian tên không có tên thay thế, đó sẽ là một điều tốt.
sbi

1
@unawoman: Nếu không có lý do nào khác, thì vì không gian tên chưa được đặt tên cung cấp cùng một cơ chế để tạo biến, hằng, hàm và kiểu bên trong TU của chúng. static class ... , OTOH, sẽ không hoạt động.
sbi

2
@nbt: Bởi vì bạn không thể sử dụng các ký hiệu tĩnh làm đối số mẫu và vì nhiều người mới sẽ thấy tĩnh dễ sử dụng hơn và sau đó không được thử dùng <f function> và <algorithm> et al. Chỉ là một suy nghĩ nhanh chóng.
Sebastian Mach

2
"bởi vì bạn không cần mã soạn sẵn mà bạn cần với không gian tên chưa được đặt tên"? "Mã boilerplate" là gì? Cái gì đó ngoài " namespace {" và " }"?
towi

1
@ErikAronesty Nếu bạn có "lớp cục bộ" trong một tệp khác có cùng tên thì bạn sẽ vi phạm ODR.
LF

32

Tôi sẽ cố gắng trả lời câu hỏi của bạn, mặc dù nó là một câu hỏi cũ, và nó không giống rất quan trọng (nó thực sự không phải là rất quan trọng của riêng mình ), và nó đã nhận được câu trả lời khá tốt rồi. Lý do tôi muốn trả lời là nó liên quan đến các vấn đề cơ bản của quá trình phát triển tiêu chuẩn và thiết kế ngôn ngữ khi ngôn ngữ dựa trên một ngôn ngữ hiện có: khi nào thì các tính năng ngôn ngữ không được dùng, loại bỏ hoặc thay đổi theo những cách không tương thích?

Trong C ++, có thể sử dụng từ khóa static trong một đơn vị dịch để ảnh hưởng đến khả năng hiển thị của một biểu tượng (khai báo biến hoặc hàm).

Mối liên kết thực sự.

Trong n3092, tính năng này không được dùng nữa:

Việc ngừng sử dụng cho biết:

  • Các ý định để loại bỏ một số tính năng trong tương lai; điều này không có nghĩa là các tính năng không dùng nữa sẽ bị xóa trong bản sửa đổi tiêu chuẩn tiếp theo hoặc chúng phải bị xóa "sớm", hoặc hoàn toàn. Và các tính năng không dùng nữa có thể bị xóa trong bản sửa đổi tiêu chuẩn tiếp theo.
  • Một nỗ lực chính thức để ngăn cản việc sử dụng nó .

Điểm thứ hai là quan trọng. Mặc dù không bao giờ có một lời hứa chính thức rằng chương trình của bạn sẽ không bị phá vỡ, đôi khi âm thầm, theo tiêu chuẩn tiếp theo, ủy ban nên cố gắng tránh phá vỡ mã "hợp lý". Việc không dùng nữa sẽ cho các lập trình viên biết rằng việc phụ thuộc vào một số tính năng là không hợp lý .

Tuy nhiên, nó nhấn mạnh rằng để tương thích với C (và khả năng biên dịch các chương trình C thành C ++), việc không dùng nữa thật khó chịu. Tuy nhiên, việc biên dịch một chương trình C trực tiếp dưới dạng C ++ có thể là một trải nghiệm khó chịu, vì vậy tôi không chắc liệu nó có đảm bảo được sự cân nhắc hay không.

Điều rất quan trọng là phải bảo toàn một tập hợp con chung C / C ++, đặc biệt là đối với các tệp tiêu đề. Tất nhiên, statickhai báo toàn cục là khai báo ký hiệu có liên kết nội bộ và điều này không hữu ích lắm trong tệp tiêu đề.

Nhưng vấn đề không bao giờ chỉ là khả năng tương thích với C, mà là khả năng tương thích với C ++ hiện có: có rất nhiều chương trình C ++ hợp lệ hiện có sử dụng statickhai báo toàn cục. Mã này không chỉ hợp pháp về mặt hình thức, mà còn hợp lý, vì nó sử dụng một đặc điểm ngôn ngữ được xác định rõ theo cách mà nó được dự định sử dụng .

Chỉ bởi vì bây giờ có một "cách tốt hơn" (theo một số người) để làm điều gì đó không làm cho các chương trình được viết theo cách cũ "xấu" hoặc "không hợp lý". Khả năng sử dụng statictừ khóa trên khai báo các đối tượng và hàm ở phạm vi toàn cục được hiểu rõ trong cả cộng đồng C và C ++, và thường được sử dụng đúng cách nhất.

Tương tự, tôi sẽ không thay đổi phôi kiểu C doublethành static_cast<double>chỉ vì "phôi kiểu C là xấu", vì static_cast<double>thêm thông tin bằng không và không an toàn.

Ý tưởng rằng bất cứ khi nào một cách mới để làm điều gì đó được phát minh, tất cả các lập trình viên sẽ vội vã viết lại mã làm việc đã được xác định rõ ràng hiện có của họ thật là điên rồ. Nếu bạn muốn loại bỏ tất cả các vấn đề và sự xấu xí kế thừa của C, bạn không thay đổi C ++, bạn phát minh ra một ngôn ngữ lập trình mới. Việc loại bỏ một nửa việc sử dụng statichầu như không làm cho C ++ ít C xấu hơn.

Thay đổi mã cần một lời biện minh, và "cũ là xấu" không bao giờ là lời biện minh cho những thay đổi mã.

Thay đổi ngôn ngữ phá vỡ cần một sự biện minh rất mạnh mẽ. Làm cho ngôn ngữ trở nên đơn giản hơn một chút không bao giờ là lý do biện minh cho một sự thay đổi đột phá.

Các lý do được đưa ra tại sao staticxấu chỉ là yếu đáng kể, và thậm chí không rõ tại sao cả hai đối tượng và khai báo hàm không được dùng cùng nhau - việc xử lý chúng khác nhau hầu như không làm cho C ++ đơn giản hơn hoặc trực giao hơn.

Vì vậy, thực sự, đó là một câu chuyện buồn. Không phải vì hậu quả thực tế mà nó gây ra: nó không có hậu quả thực tế chính xác. Nhưng vì nó cho thấy sự thiếu hiểu biết rõ ràng từ ủy ban ISO.


5
Như bản thân bạn đã chỉ ra, điểm không nên dùng nó là không khuyến khích việc sử dụng nó. Tuy nhiên, bạn không lập luận rằng việc ngăn cản việc sử dụng nó là sai. Tôi chắc chắn hy vọng rằng không ai ở ngoài đó khuyến khích mọi người sử dụng khai báo tĩnh có phạm vi không gian tên trên không gian tên ẩn danh. Không, trừ khi họ đặc biệt cần phải C. cross-compile
Nicol Bolas

2
Tôi không quan tâm nhiều đến việc mọi người sử dụng phạm vi toàn cầu statichoặc không gian tên ẩn danh, tôi cũng không khuyến khích hay ngăn cản. Quan điểm của tôi là nếu bạn thực sự muốn không khuyến khích mọi người sử dụng không gian tên ẩn danh, bạn phải đưa ra lý lẽ xác đáng cho họ. Trong thực tế, tôi tin rằng trong hầu hết các thực thể triển khai được khai báo trong một không gian tên chưa được đặt tên là các ký hiệu được xuất với một tên ngẫu nhiên, do đó, bảng xuất sẽ phát triển. Các thực thể được khai báo là static, OTOH, không được xuất theo bất kỳ cách nào. Vì vậy, nhiều người lựa chọn, dựa trên quan sát đó, để sử dụng static.
tò mò

2
Như chính bạn đã chỉ ra, điểm của việc không dùng nó là không khuyến khích việc sử dụng nó. ” Điểm không khuyến khích việc sử dụng nó là một ngày nào đó nó có thể biến mất. Quan điểm của tôi là phạm vi không gian tên staticsẽ không bao giờ biến mất, vì vậy thật sai lầm khi không dùng nó. “ Tuy nhiên, bạn không lập luận rằng việc không khuyến khích sử dụng nó là sai. ” Tôi chưa thấy lập luận thuyết phục nào cho thấy việc sử dụng phạm vi không gian tên staticlà “sai”. Không sử dụng nó chỉ để ngăn cản việc sử dụng nó là sai, bởi vì không ai thực sự tin rằng nó sẽ biến mất, và vì nó không thuyết phục mọi người rằng sử dụng nó là "sai".
tò mò

5
Toàn bộ ngôn ngữ sẽ "biến mất vào một ngày nào đó". Hãy không dùng C ++ nữa.
Lightness Races ở Orbit

2
"Theo cách tương tự, tôi sẽ không thay đổi phôi kiểu C thành nhân đôi thành static_cast <double> chỉ vì" phôi kiểu C không tốt ", vì static_cast <double> thêm thông tin bằng không và không an toàn." Cuộc chiến vĩnh viễn của tôi với nhiều kỹ sư phần mềm luôn phàn nàn về việc tôi sử dụng thường xuyên các phôi kiểu C từ nguyên thủy này sang nguyên thủy khác.
Makogan 19/07/19

14

Không được chấp nhận hay không, việc loại bỏ tính năng ngôn ngữ này sẽ phá vỡ các mã hiện có và làm phiền mọi người.

Toàn bộ vấn đề từ chối static chỉ là suy nghĩ viển vông dọc theo dòng "không gian tên ẩn danh tốt hơn không gian tĩnh" và "tham chiếu là con trỏ tốt hơn". Cười lớn.


1
"Tài liệu tham khảo là con trỏ tốt hơn"? Không, con trỏ thông minh là con trỏ thông minh hơn. Bạn không thể sử dụng tham chiếu cho bộ nhớ được cấp phát từ kho lưu trữ miễn phí heap, err.
Dan Breslau

3
Xin lỗi, tôi quên kết thúc nó bằng một nụ cười mỉa mai.
Maxim Egorushkin

2
@Dan: Đó chính xác là những gì câu trả lời này nói: "mơ tưởng" cùng một dòng suy nghĩ bị lỗi tương tự. Không gian tên chưa được đặt tên là một tính năng quan trọng, cũng giống như global-scope-static, mặc dù vì những lý do hơi khác nhau và mặc dù chúng có một số trùng lặp về khả năng ứng dụng.
Fred Nurk

@Fred, @Maxim: Xin lỗi nếu tôi hiểu nhầm hoặc nếu bộ nhớ của tôi bị lỗi. Nhưng tôi không phân loại "tham chiếu là con trỏ tốt hơn" tương đương với "không gian tên ẩn danh tốt hơn không gian tĩnh" như một trường hợp mơ tưởng. Tôi biết rõ về nỗ lực tạo ra thanh sau, nhưng tôi không nhớ có ai đưa ra đề xuất nghiêm túc để thay thế con trỏ bằng tham chiếu. Một lần nữa, có lẽ đó là nhận thức của chính tôi đang thiếu.
Dan Breslau

1
@DanBreslau: char* foo = new char; char& ref = *foo;Chỉ vì ban đầu bạn được cấp một con trỏ không nói gì về khả năng sử dụng tài liệu tham khảo của bạn.
Các cuộc đua ánh sáng trong quỹ đạo
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.