2009-10-13 30 views
77

Tôi đang cố gắng tìm ra phiên bản nào của Boost code của tôi cho rằng nó đang sử dụng. Tôi muốn làm một cái gì đó như thế này:Làm cách nào để hiển thị giá trị của #define tại thời gian biên dịch?

#error BOOST_VERSION

nhưng tiền xử lý không mở rộng BOOST_VERSION.

Tôi biết tôi có thể in nó ra vào thời gian chạy từ chương trình và tôi biết tôi có thể xem kết quả của bộ tiền xử lý để tìm câu trả lời. Tôi cảm thấy như có một cách để làm điều này trong quá trình biên dịch có thể hữu ích.

+6

Đối với du khách trong tương lai ... Chris Barry cung cấp giải pháp tổng quát khi kết thúc (không có thứ Boost cụ thể). – jww

Trả lời

47

Nếu bạn đang sử dụng Visual C++, bạn có thể sử dụng #pragma message:

#include <boost/preprocessor/stringize.hpp> 
#pragma message("BOOST_VERSION=" BOOST_PP_STRINGIZE(BOOST_VERSION)) 

Edit: Nhờ LB cho liên kết

Rõ ràng, GCC tương đương được (không kiểm tra):

#pragma message "BOOST_VERSION=" BOOST_PP_STRINGIZE(BOOST_VERSION) 
+5

Được gọi là pragmas chẩn đoán, http://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html#Diagnostic-Pragmas – LB40

+2

Sẽ rất tuyệt nếu bạn đưa vào [định nghĩa của 'BOOST_PP_STRINGIZE'] (http: // www .boost.org/doc/libs/1_63_0/boost/preprocessor/stringize.hpp) là tốt đẹp và ngắn và sao chép/có thể dán. – Timmmm

+0

Hoạt động tốt dưới gcc :) –

0

Bạn có thể viết chương trình in ra BOOST_VERSION và biên dịch và chạy nó như một phần của hệ thống xây dựng của bạn. Nếu không, tôi nghĩ bạn không may mắn.

+0

Đối với trường hợp phiên bản phần mềm được xác định trong tiêu đề, bạn có thể an toàn (và đó là câu trả lời hay). Nhưng như một giải pháp chung, một nhược điểm có thể là trong việc ứng dụng thử nghiệm của bạn và ứng dụng thực của bạn có cùng giá trị của # define - tùy thuộc vào đường dẫn bao gồm của chúng, các giá trị khác có thể được sử dụng để đặt giá trị của giá trị đó , CFLAGS được chuyển tới trình biên dịch, v.v. – KeyserSoze

+0

In ra từ chương trình thực của bạn. Nếu đồ họa, hãy đặt nó trong hộp thoại "about". Nếu dòng lệnh, làm cho nó một tùy chọn (một phần của --version, có thể). Nếu một daemon, hãy ghi nó vào một tệp nhật ký. Nếu được nhúng, hãy tìm cách khác. – divegeek

+0

@swillden - OP muốn nó tại thời gian biên dịch, không phải lúc chạy. –

11

Theo như tôi biết '#error' chỉ sẽ in chuỗi, trên thực tế, you don't even need to use quotes.

Bạn đã thử viết mã có mục đích không chính xác khác nhau bằng cách sử dụng "BOOST_VERSION"? Có lẽ một cái gì đó như "blah [BOOST_VERSION] = foo;" sẽ cho bạn biết một cái gì đó như "chuỗi chữ 1.2.1 không thể được sử dụng như một địa chỉ mảng". Nó sẽ không phải là một thông báo lỗi khá, nhưng ít nhất nó sẽ cho bạn thấy giá trị có liên quan. Bạn có thể chơi xung quanh cho đến khi bạn tìm thấy một lỗi biên dịch cho bạn biết giá trị.

+0

Giải quyết vấn đề tốt. +1 –

+0

Điều đó không hiệu quả, vì BOOST_VERSION là một số nguyên, nhưng tôi đã thấy nó với câu lệnh sau: 'std :: vector ;' trong gcc 4.4.1. Cảm ơn! –

+0

Lưu ý rằng với Visual C++, bạn sẽ phải sử dụng câu trả lời của Bojan Resnik. –

0

Bạn đang tìm kiếm

#if BOOST_VERSION != "1.2" 
#error "Bad version" 
#endif 

Không tuyệt vời nếu BOOST_VERSION là một chuỗi, giống như tôi đã giả định, nhưng cũng có thể có nguyên nhân được xác định cho các số lớn, nhỏ và sửa đổi.

+0

Tôi nghĩ rằng người gửi không muốn (chỉ) thực thi một giá trị cụ thể, họ muốn xem giá trị hiện tại là gì. – KeyserSoze

2

Bạn cũng có thể tiền xử lý tệp nguồn và xem giá trị tiền xử lý đánh giá là gì.

1

Nhìn vào đầu ra của bộ tiền xử lý là điều gần nhất với câu trả lời bạn yêu cầu.

Tôi biết bạn đã loại trừ (và các cách khác), nhưng tôi không chắc chắn lý do. Bạn có một vấn đề đủ cụ thể để giải quyết, nhưng bạn chưa giải thích tại sao bất kỳ phương pháp "bình thường" nào không hoạt động tốt cho bạn.

+0

Đây có lẽ là câu trả lời đúng cho vấn đề chung. – jww

0

BOOST_VERSION được định nghĩa trong tệp tiêu đề tăng cường phiên bản.hpp.

0

Hãy xem tài liệu Boost cũng như về cách bạn đang sử dụng macro:

Trong tài liệu tham khảo để BOOST_VERSION, từ http://www.boost.org/doc/libs/1_37_0/libs/config/doc/html/boost_config/boost_macro_reference.html#boost_config.boost_macro_reference.boost_helper_macros:

Mô tả số lượng tăng phiên bản trong định dạng XXYYZZ ví dụ rằng: (BOOST_VERSION % 100) là phiên bản phụ nhỏ , ((BOOST_VERSION/100) % 1000) là phiên bản phụ và (BOOST_VERSION/100000) là chính phiên bản.

83

BOOST_PP_STRINGIZE dường như là một giải pháp tuyệt vời cho C++, nhưng không phải cho thường xuyên C.

Đây là giải pháp của tôi cho GNU CPP:

/* Some test definition here */ 
#define DEFINED_BUT_NO_VALUE 
#define DEFINED_INT 3 
#define DEFINED_STR "ABC" 

/* definition to expand macro then apply to pragma message */ 
#define VALUE_TO_STRING(x) #x 
#define VALUE(x) VALUE_TO_STRING(x) 
#define VAR_NAME_VALUE(var) #var "=" VALUE(var) 

/* Some example here */ 
#pragma message(VAR_NAME_VALUE(NOT_DEFINED)) 
#pragma message(VAR_NAME_VALUE(DEFINED_BUT_NO_VALUE)) 
#pragma message(VAR_NAME_VALUE(DEFINED_INT)) 
#pragma message(VAR_NAME_VALUE(DEFINED_STR)) 

định nghĩa trên cho kết quả:

test.c:10:9: note: #pragma message: NOT_DEFINED=NOT_DEFINED 
test.c:11:9: note: #pragma message: DEFINED_BUT_NO_VALUE= 
test.c:12:9: note: #pragma message: DEFINED_INT=3 
test.c:13:9: note: #pragma message: DEFINED_STR="ABC" 

Đối với "được xác định là interger", "được định nghĩa là chuỗi""được xác định nhưng không có giá trị" biến số, chúng hoạt động tốt. Chỉ đối với biến số "không được xác định", chúng hiển thị chính xác giống như tên biến ban đầu. Bạn phải sử dụng nó - hoặc có thể ai đó có thể cung cấp một giải pháp tốt hơn.

+0

tuyệt vời! Bất kỳ kinh nghiệm trong ARM RVCT? có vẻ như không có tính năng "Chuỗi hóa" như GCC http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0491c/CIHHDEAA.html – xdan

+1

Giải pháp tuyệt vời. Tuy nhiên, nếu tôi muốn hiển thị kích thước của giá trị được tính toán thời gian biên dịch, ví dụ: kích thước của một cấu trúc phức tạp, điều này có thể được thực hiện?Phương pháp được đề xuất trong câu trả lời này dường như tạo ra 'DEFINED_INT = (sizeof (MY_STRUCT))', không có toán tử 'sizeof' được đánh giá. – Carl

+0

(bổ sung chú thích: không bất ngờ, vì nó là trình biên dịch chứ không phải là bộ xử lý trước sẽ đánh giá 'sizeof', tuy nhiên, vẫn tò mò nếu có cách thông minh để đạt được điều này.) – Carl

69

Tôi biết rằng đây là một thời gian dài sau truy vấn ban đầu, nhưng điều này vẫn có thể hữu ích.

Điều này có thể được thực hiện trong GCC bằng cách sử dụng toán tử xâu chuỗi "#", nhưng nó yêu cầu hai giai đoạn.

#define XSTR(x) STR(x) 
#define STR(x) #x 

Giá trị của một macro sau đó có thể được hiển thị với:

#pragma message "The value of ABC: " XSTR(ABC) 

Xem: 3.4 Stringification trong tài liệu trực tuyến gcc.

+1

Tôi tò mò là tại sao nó đòi hỏi hai giai đoạn –

+3

@VincentFourmond Không có giai đoạn XSTR, macro không được mở rộng. Vì vậy, nếu bạn đã làm #define ABC 42 \ n STR (ABC), bạn sẽ nhận được "ABC". Xem https://gcc.gnu.org/onlinedocs/cpp/Stringification.html – rob05c

+0

Điều này cũng hoạt động tốt với Xcode 8, ví dụ: thay thế ABC bằng '__IPHONE_9_3'. – funroll

0
#define a <::BOOST_VERSION> 
#include a 
MSVC2015: fatal error C1083: Không thể mở bao gồm file: ':: 106.200': Không có tập tin hoặc thư mục

Làm việc ngay cả khi preprocess to file được kích hoạt, thậm chí nếu thẻ không hợp lệ là trình bày:

#define a <::'*/`#> 
#include a 
MSVC2015: lỗi nghiêm trọng C10 83: Không thể mở bao gồm file: '::' */`# ': Không có tập tin hoặc thư mục
GCC4.x: cảnh báo: thiếu chấm dứt' nhân vật [-Winvalid-pp-thẻ]
#define một < :: '*/`# >
1

Nếu không tăng:

  1. xác định cùng một vĩ mô một lần nữa và trình biên dịch mình sẽ đưa ra cảnh báo.

  2. Từ cảnh báo, bạn có thể xem vị trí của định nghĩa trước đó.

  3. vi tệp định nghĩa trước đó.

[email protected]:~/cpp$ g++ shiftOper.cpp 
shiftOper.cpp:7:1: warning: "LINUX_VERSION_CODE" redefined 
shiftOper.cpp:6:1: warning: this is the location of the previous definition 

#define LINUX_VERSION_CODE 265216 
#define LINUX_VERSION_CODE 666 

int main() 
{ 

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