gcc unexpected C static_assert error: expression in static assertion is not constant

I have some C code which builds OK with gcc-11 and earlier but not gcc-12 and later.
This illustrates the problem (this isn’t the actual code I’m working on):

#include <stdint.h>
#include <assert.h>

// forward testfunc declaration
void testfunc(int testvar);

int main()
{
  static_assert(((uintptr_t)testfunc != 0), "error!!");
}

// testfunc definition
void testfunc(int testvar) {}

see also: https://godbolt.org/z/vMf31zoaT

With gcc-12, if I move the testfunc() definition before main(), then it builds OK.
But with testfunc() after main(), I get the build error:
error: expression in static assertion is not constant

I don’t understand why I get this error as the function address is constant.
This occurs several times in the existing code I’m working on. I could fix it by modifying the code, but I’d prefer not to as it would mean a lot of changes. Any ideas how to fix this?
Just to be clear: the code above illustrates the problem. The actual code I’m working on uses static_assert in a macro to detect if a const function pointer is set to NULL in error, but it gets the same error with gcc-12.

14

I don’t understand why I get this error as the function address is constant.

Yes, the function address is constant, in the sense that C defines it as an address constant, one of the forms of constant expression. (C17 6.6/9)

But C places a stronger requirement on the expression in a static assertion: it must be an integer constant expression, and even though your expression has integer type, it does not qualify. These are the requirements:

An integer constant expression shall have integer type and shall only
have operands that are integer constants, enumeration constants,
character constants, sizeof expressions whose results are integer
constants, _Alignof expressions, and floating constants that are the
immediate operands of casts. Cast operators in an integer constant
expression shall only convert arithmetic types to integer types,
except as part of an operand to the sizeof or _Alignof operator.

(C17 6.6/6)

Pointers are not among the operands the spec allows in integer constant expressions, neither in general nor as operands in cast (sub)expressions, except that they probably may appear in sizeof and _Alignof (sub)expressions.

Any ideas how to fix this?

Option 1: Remove the static assertions in question. If your program contains (direct) calls to undefined functions, or if it attempts to take the address of an undefined function, then you will know it because of link errors. On the other hand, until linking, your C implementation does not know whether there are any such calls, so even if it accepted static assertions such as those in your example, they would not tell you anything useful.

Option 2: Convert the static assertions to ordinary assertions. The expression in an ordinary assertion does not even have to be a constant expression, much less an integer constant expression. Of course, these are not evaluated until runtime, and depending on how you build the program, they may be suppressed so that they are not evaluated at all.

Option 3: Stick with Gcc 11, since that apparently accepts the static assertions you have (which it is within its rights to do). This is probably not a viable long-term strategy, but it can keep your builds working until you finish implementing option 1 or 2.

I looked for a command-line option in Gcc 12 that would provide the old behavior for such assertions, but if there is one, it eluded me.

1

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật