2012-12-02 80 views
6

Có thể một trong C++ 11 bằng cách nào đó trong gcc đánh dấu một hàm (không phải là phương thức lớp) là const cho biết đó là thuần túy và không sử dụng bộ nhớ chung.Chức năng thuần túy trong C++ 11

Tôi đã thử gcc 's __attribute__((const)) và chính xác là chính xác những gì tôi muốn. Nhưng nó không tạo ra bất kỳ lỗi thời gian biên dịch nào khi bộ nhớ toàn cục được chạm vào trong hàm.

Sửa 1

Hãy cẩn thận. Tôi có nghĩa là chức năng tinh khiết. Chức năng không liên tục. GCC của thuộc tính là một chút bối rối. Các hàm thuần túy chỉ sử dụng các đối số của chúng.

+0

cũng không chắc chắn ý bạn là gì, nhưng bạn đã thử 'constexpr' –

+0

KHÔNG PHẢI LÀ. Ý tôi là tinh khiết không liên tục. Các thuộc tính của GCC có chút ít gây nhầm lẫn. – Cartesius00

+1

Tôi nghĩ bạn cần phải thuật lại câu hỏi của bạn, bởi vì bạn có thuộc tính đúng. Rằng nó không tạo ra cảnh báo bạn muốn là một vấn đề khác - ít nhất là khi lấy câu hỏi của bạn theo giá trị khuôn mặt. –

Trả lời

4

Bạn đang tìm kiếm constexpr? Điều này cho trình biên dịch biết rằng hàm có thể được đánh giá tại thời gian biên dịch. Hàm constexpr phải có kiểu trả về và kiểu tham số theo nghĩa đen và phần thân chỉ có thể chứa các xác nhận tĩnh, typedef, sử dụng các khai báo và chỉ thị và một câu lệnh trả về. Hàm constexpr có thể được gọi theo biểu thức không đổi.

constexpr int add(int a, int b) { return a + b; } 

int x[add(3, 6)]; 

Sau khi xem xét ý nghĩa của __atribute__((const)), câu trả lời là không, bạn không thể làm điều này với tiêu chuẩn C++. Sử dụng constexpr sẽ đạt được hiệu quả tương tự, nhưng chỉ trên một tập hợp nhiều chức năng giới hạn hơn. Không có gì ngăn cản một trình biên dịch tự thực hiện các tối ưu hóa này, miễn là chương trình được biên dịch hoạt động theo cùng một cách (quy tắc as-if).

+0

Không không không, ý tôi là các chức năng thuần túy. Xem tôi chỉnh sửa, xin vui lòng. – Cartesius00

+0

@Martin Đã thêm –

+0

Cảm ơn bạn. Thuộc tính 'constexpr' gần như vô dụng. Có lẽ chúng ta hãy chờ thêm một chút nữa. Có thể một số thuộc tính 'gcc' cụ thể khác có thể hữu ích. – Cartesius00

0

chỉ sử dụng tiêu chuẩn C++ 11:

namespace g{ int x; } 

constexpr int foo() 
{ 
    //return g::x = 42; Nah, not constant 
    return 42;  // OK 
} 

int main() 
{} 

đây là một ví dụ:

constexpr int foo(int blah = 0) 
{ 
    return blah + 42;  // OK 
} 

int main(int argc, char**) 
{ 
    int bah[foo(2)];   // Very constant. 
    int const troll = foo(argc); // Very non-constant. 
} 

Ý nghĩa của GCC của __attribute__(const) được diễn tả trong GNU compiler docs như & hellip;

Nhiều chức năng không kiểm tra bất kỳ giá trị nào ngoại trừ đối số của chúng và không có hiệu ứng ngoại trừ giá trị trả lại. Về cơ bản, đây chỉ là lớp nghiêm ngặt hơn một chút so với thuộc tính pure bên dưới, vì chức năng không được phép đọc bộ nhớ toàn cầu.

Có thể thực hiện điều đó có nghĩa là kết quả hàm chỉ nên phụ thuộc vào đối số và hàm sẽ không có tác dụng phụ.

Điều này cho phép một lớp tổng quát hơn các chức năng hơn 11 C++ constexpr, mà làm cho chức năng inline, hạn chế tranh cãi và kết quả chức năng để loại đen, và hạn chế những điều khoản về "hoạt động" của cơ quan chức năng để một đơn Tuyên bố return, trong đó (C++ 11 §7.1.5/3)

- mọi lần gọi hàm tạo và chuyển đổi ngầm được sử dụng để khởi tạo giá trị trả về (6.6.3, 8.5) sẽ là một trong những điều khoản được cho phép biểu thức liên tục (5.19)

Ví dụ, rất khó (tôi nghĩ không phải là không thể, nhưng khó) để thực hiện một hàm constexprsin.

Nhưng sự tinh khiết của các vấn đề kết quả duy nhất để hai bên:

  • Khi biết đến là tinh khiết, trình biên dịch có thể bõ mẫu âm chót cuộc gọi với kết quả được biết đến.
    Đây chủ yếu là tối ưu hóa mã do macro tạo. Thay thế macro bằng các hàm inline để tránh tạo ra các biểu thức con giống hệt nhau.

  • Khi được biết là tinh khiết, một lập trình viên có thể xóa hoàn toàn cuộc gọi.
    Đây chỉ là vấn đề về tài liệu thích hợp. :-)

Vì vậy, thay vì tìm cách thể hiện độ tinh khiết của ví dụ: sin trong ngôn ngữ, tôi khuyên bạn chỉ nên tránh tạo mã thông qua các macro và ghi lại các hàm thuần túy như vậy.

Và sử dụng constexpr cho các chức năng mà tại đó thực tế có thể (không may, tính đến tháng 12 năm 2012 trình biên dịch Visual C++ mới nhất chưa hỗ trợ constexpr).


Có câu hỏi SO trước về the relationship between pure and constexpr. Chủ yếu, mỗi hàm constexprthuần túy, nhưng không phải ngược lại.

+0

Không không không, ý tôi là hàm thuần túy, không phải hàm số liên tục. – Cartesius00

+0

@Martin: cũng có một chút thô lỗ khi downvote câu trả lời trên tài khoản của bạn mô tả vấn đề là mơ hồ enought để gây ra hai câu trả lời như vậy, cho đến nay. "một chút" thô lỗ? xin lỗi, tôi có nghĩa là, * khá * thô lỗ. jeez. –

+0

Vấn đề của tôi? Câu hỏi đặt ra là dành cho những người biết ý nghĩa của 'thuần khiết' và thuộc tính của GCC. – Cartesius00

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