2010-02-08 45 views
7

Năm trước, tôi tin rằng C hoàn toàn thuần khiết so với C++ vì trình biên dịch không thể tạo ra bất kỳ mã nào mà bạn không thể dự đoán được. Bây giờ tôi tin rằng các ví dụ truy cập bao gồm các rào cản từ khóa và bộ nhớ volatile (trong lập trình đa xử lý hoặc trình điều khiển thiết bị cho các thiết bị phần cứng được ánh xạ bộ nhớ, nơi ngôn ngữ lắp ráp đơn giản thậm chí còn thuần khiết hơn các trình tối ưu hóa của trình biên dịch C).Cách vô tình tạo đối tượng tạm thời trong C++?

Hiện tại tôi đang cố gắng liệt kê những điều không thể đoán trước mà trình biên dịch C++ có thể thực hiện. Khiếu nại chính dính trong tâm trí của tôi về C++ là trình biên dịch sẽ ngầm khởi tạo các đối tượng tạm thời, nhưng tôi tin rằng những trường hợp này có thể được mong đợi. Các trường hợp tôi đang nghĩ đến việc là:

  • khi một lớp định nghĩa một constructor sao chép cho một loại khác hơn là chính nó, mà không sử dụng các từ khóa explicit
  • khi một lớp định nghĩa một nhà điều hành chuyển đổi quá tải: operator()
  • khi một chức năng chấp nhận một đối tượng theo giá trị thay vì bằng cách tham khảo
  • khi một hàm trả về một đối tượng bằng giá trị thay vì bằng cách tham khảo

có phải lại bất kỳ người nào khác?

+0

+1: thú vị khi nói đến các hệ thống nhúng. – jldupont

+3

Đây là tất cả được xác định trong tiêu chuẩn và do đó có thể được dự đoán - những người không thể dự đoán là hành vi không xác định – Mark

+1

Trong C bạn có chuyển đổi tiềm ẩn (phôi), vì vậy tôi sẽ không nói đó là "thuần túy". – Manuel

Trả lời

2

Tôi cho rằng "không thể đoán trước" có nghĩa là "một cái gì đó phù hợp với tiêu chuẩn nhưng khác với những gì người lập trình mong đợi khi viết mã", phải không?

Tôi đoán bạn có thể thấy từ mã nơi các đối tượng được khởi tạo hoặc sao chép, ngay cả khi nó có thể không rõ ràng. Nó có thể là khó hiểu mặc dù.

Một số nội dung chỉ được triển khai theo những cách nhất định bởi (tất cả?) Nhà cung cấp trình biên dịch, nhưng có thể được thực hiện khác nhau. Ví dụ: liên kết trễ (còn gọi là phương thức ảo quá tải) thường được triển khai bằng cách sử dụng con trỏ hàm trong nền. Đây có lẽ là cách nhanh nhất để làm điều đó, nhưng tôi cho rằng nó có thể được thực hiện khác nhau và điều đó sẽ là bất ngờ. Tôi không biết bất kỳ trình biên dịch mặc dù nó không khác nhau.

Rất nhiều nội dung bất ngờ theo nghĩa C++ quá phức tạp - hầu như không ai hiểu được ngôn ngữ đầy đủ. Vì vậy, bất ngờ cũng phụ thuộc vào kiến ​​thức của bạn.

+0

+1 cho một phân tích tốt về những gì có vẻ là vấn đề trong việc hiểu câu hỏi. –

2

12,2 đối tượng tạm thời

1 là tạm thời loại lớp được tạo ra trong bối cảnh khác nhau: ràng buộc một rvalue đến một tài liệu tham khảo (8.5.3), trả lại một rvalue (6.6.3), a chuyển đổi tạo giá trị (4.1, 5.2.9, 5.2.11, 5.4), ném ngoại lệ (15.1), nhập trình xử lý (15.3) và trong một số lần khởi tạo (8.5).

4 Có hai ngữ cảnh trong đó thời gian bị phá hủy tại điểm khác so với kết thúc của fullexpression.

Thực tế tôi khuyên bạn nên xem toàn bộ 12.2

Hiện tại, tôi đang cố gắng liệt kê những điều không thể đoán trước mà trình biên dịch C++ có thể thực hiện. Các khiếu nại chính mà dính trong tâm trí của tôi về C + + là rằng trình biên dịch sẽ ngầm nhanh chóng đối tượng tạm thời, nhưng tôi tin rằng những trường hợp này tất cả có thể được mong đợi.

Trình biên dịch không tạo ra thời gian tạm thời - nó tuân theo tiêu chuẩn. Trừ khi, tất nhiên, khi bạn gọi hành vi không xác định. Lưu ý, có một cái gì đó gọi là sao chép-elision và tối ưu hóa giá trị trả về mà thực sự có thể làm giảm số lượng các thời gian mà nếu không sẽ được tạo ra.

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