2010-09-23 38 views
6

Đây là những gì tôi đã được mã hóa ngày naygọi Chức năng trong sai trật tự

#include <iostream> 
using namespace std; 

int function1() 
{ 
    cout<<"hello from function1()"; return 0; 
} 

int function2() 
{ 
    cout<<"hello from function2()"; return 0; 
} 

int main() 
{ 
    int func_diffresult = 0; 
    func_diffresult = function1() - function2(); 
    cout<<func_diffresult; /** prints 0 correctly **/ 
} 

đầu ra là lấy được hello from function2()hello from function1(). Tôi nghĩ rằng đầu ra phải là hello from function1()hello from function2(). Trình biên dịch của tôi có chơi với tôi không?

+0

Có lẽ bạn có lỗi đánh máy trong mã đó ... Tôi thấy hai khai báo 'hàm1'. – dmckee

+1

Điều này sẽ không biên dịch bạn đang thiếu chức năng thứ hai! Đổi tên hàm thứ hai thành hàm2(). – Secko

+0

@dmckee đã sửa lỗi đánh máy. – Raghvan

Trả lời

10

Thứ tự đánh giá đối số của nhà cung cấp -unspecified. Vì vậy, các hàm có thể được gọi theo thứ tự.

5

Toán tử - hiệu quả trở thành operator-(function1(), function2()) và thứ tự đánh giá tham số chức năng được cố ý không xác định.


ghi chú liên quan:

Một lý do thực sự tốt để lại nó không xác định là để xử lý công ước gọi một cách hiệu quả. Ví dụ: quy ước gọi C yêu cầu thông số được đẩy lên ngăn xếp theo thứ tự đảo ngược.

Do đó, việc đánh giá các hàm theo thứ tự ngược lại có ý nghĩa vì kết quả có thể được đẩy ngay lập tức. Để đánh giá các tham số từ trái sang phải và sau đó đẩy các kết quả từ phải sang trái liên quan đến việc lưu trữ tất cả các kết quả trước khi đẩy bất kỳ kết quả nào. Nếu bạn thực sự cần phải làm điều này, bạn có thể làm điều đó bằng tay. Nếu nó không quan trọng với bạn, lợi ích hiệu suất có thể làm.

+0

Đó là sự thật cho 'cdecl' trên x86, nhưng không phải tất cả các quy ước gọi đều đẩy giá trị lên ngăn xếp. Một số người trong số họ vượt qua đối số trong sổ đăng ký. – dan04

+0

Tuyệt đối. Đó là lý do tại sao đơn đặt hàng là "không xác định" thay vì "từ phải sang trái" (hoặc "từ trái sang phải") - và ai biết được quy ước gọi điện nào sẽ được sử dụng trong tương lai? Tốt hơn để nói "không dựa vào thứ tự kết hợp thứ tự tham số" và để các trình biên dịch thực hiện nó hiệu quả nhất có thể. – Zooba

2

Tiêu chuẩn ISO không đảm bảo thứ tự các biểu thức con sẽ được đánh giá.

Từ C++ 0x dự thảo tiêu chuẩn:


1,9. Chương trình thực hiện:
          :
13/ tiếp nối theo trước khi là một bất đối xứng, bắc cầu, mối quan hệ cặp-khôn ngoan giữa đánh giá thực hiện bởi một chủ đề duy nhất, mà gây ra một trật tự một phần trong số những người đánh giá. Đưa ra hai đánh giá A và B, nếu A được sắp xếp trước B, thì việc thực hiện A sẽ đứng trước việc thực hiện B. Nếu A không được sắp xếp trước khi B và B không được giải trình tự trước A, thì A và B không được kết nối. [Lưu ý: Việc thực hiện các đánh giá không được tuân thủ có thể trùng lặp.]

Đánh giá A và B được sắp xếp theo trình tự xác định khi A được sắp xếp trước khi B hoặc B được sắp xếp trước A, nhưng không xác định. [Lưu ý: đánh giá Indeterminately trình tự không thể trùng nhau, nhưng một trong hai có thể được thực hiện đầu tiên.]
          :
15/ Trừ khi có ghi chú, đánh giá của toán hạng của các nhà khai thác cá nhân và của subexpressions của biểu thức cá nhân là không có kết quả.
          :
Khi gọi một hàm (có hoặc không có chức năng là inline), mỗi giá trị tính toán và phụ ảnh hưởng kết hợp với bất kỳ biểu hiện lý luận, hoặc với biểu thức postfix chỉ định hàm được gọi, được lập trình tự trước khi thực hiện mọi biểu thức hoặc câu lệnh trong phần thân của hàm được gọi [Chú thích: Nói cách khác, các phép thực hiện hàm không xen kẽ nhau]. [Lưu ý: Các tính toán giá trị và các tác dụng phụ liên quan đến các biểu thức đối số khác nhau không được tuân thủ.]

Mọi đánh giá trong chức năng gọi điện (bao gồm các cuộc gọi chức năng khác) không được giải trình cụ thể trước hoặc sau khi thực hiện phần thân chức năng được sắp xếp không xác định đối với việc thực thi hàm được gọi.


Nói cách khác, việc triển khai sẽ miễn phí để sắp xếp các cuộc gọi bằng bất kỳ phương pháp nào họ muốn. Tuy nhiên, các cuộc gọi chức năng được xử lý đặc biệt theo chú thích - chúng thực hiện không phải xen kẽ.

+0

Chỉ cần tò mò: Liệu nó có nghĩa là function1 và function2 cũng có thể được xen kẽ (và do đó chạy song song) trên một kiến ​​trúc đa CPU? – Chubsdad

+0

Tôi đoán vậy. Vì Thuật ngữ chuẩn cho A trước B, hoặc B trước A, nhưng không xác định là 'không xác định trình tự'. Nhưng kể từ khi Standard nói 'Unsequenced', IMO, nó có nghĩa là các lời gọi hàm cũng có thể được xen kẽ. – Chubsdad

+0

@Chubsdad: có, xem bản cập nhật (câu cuối cùng và lưu ý ở cuối đoạn đầu tiên của ** 13 ** và toàn bộ đoạn thứ hai của ** 13 **). Đối với không có kết quả, họ có thể chồng lên nhau. Đối với không xác định trình tự, chúng vẫn được sắp xếp theo trình tự (không trùng lặp) nhưng nó có thể đi AB hoặc BA. Câu hỏi liên quan đến một thao tác không được kết nối sao cho nó _could_ trùng lặp. – paxdiablo

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