[Bug c++/115196] Bad error message when using library functions from versions before they were introduced
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115196 --- Comment #5 from Halalaluyafail3 --- (In reply to Jonathan Wakely from comment #4) > (In reply to Halalaluyafail3 from comment #0) > > This note doesn't seem to be very helpful, it mentions adding an extra > > '#include' when one is already present. A better error message here > > would be to omit the note, or to make it mention changing the selected C++ > > standard version. > > If you'd tried gcc trunk on godbolt you'd have seen that's exactly what > happens: > > :3:10: note: 'std::to_address' is only available from C++20 onwards > > There was just a typo which made gcc think std::to_address is part of > in C++11, so if it wasn't declared in your program then it must be > because you didn't include . > > After the fix it correctly suggests using at least C++20. My bad, I only tested this on GCC 14.1 and assumed that GCC 14.1 was recent enough that it wouldn't have been changed.
[Bug c++/115196] New: Bad error message when using library functions from versions before they were introduced
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115196 Bug ID: 115196 Summary: Bad error message when using library functions from versions before they were introduced Product: gcc Version: 14.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: luigighiron at gmail dot com Target Milestone: --- GCC generates some error messages when attempting to use library functions without including the appropriate header, indicating that the appropriate header should be included. This seems to act incorrectly when attempting to use a library function from a version before the function was introduced, for example: #include int main(){ std::to_address((void*)0); } std::to_address was introduced in C++20 so when using the default compilation settings, i.e. C++17 this code is invalid. This is the generated error message from testing on godbolt with GCC 14.1.0: : In function 'int main()': :3:10: error: 'to_address' is not a member of 'std' 3 | std::to_address((void*)0); | ^~ :2:1: note: 'std::to_address' is defined in header ''; this is probably fixable by adding '#include ' 1 | #include +++ |+#include 2 | int main(){ This note doesn't seem to be very helpful, it mentions adding an extra '#include' when one is already present. A better error message here would be to omit the note, or to make it mention changing the selected C++ standard version.
[Bug c/115109] Incorrect type of enumeration constant in redeclaration of enumeration constant (C23)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115109 --- Comment #4 from Halalaluyafail3 --- (In reply to Halalaluyafail3 from comment #3) > enum E { a = 1L, b = _Generic(a, enum E: 2) }; /* { dg-warning "outside the > range" } */ Seems like I copied this wrong, the comment should be a part of the first quote.
[Bug c/115109] Incorrect type of enumeration constant in redeclaration of enumeration constant (C23)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115109 --- Comment #3 from Halalaluyafail3 --- (In reply to uecker from comment #2) > PATCH: https://gcc.gnu.org/pipermail/gcc-patches/2024-May/652093.html I'm confused about the tests added here: > enum H { x = 1 }; > enum H { x = 2UL + UINT_MAX }; Shouldn't this be a constraint violation if unsigned long is wide than unsigned? > If two declarations of the same type have a member-declaration or > enumerator-list, one shall not be nested within the other and both > declarations shall fulfill all requirements of compatible types (6.2.7) > with the additional requirement that corresponding members of structure or > union types shall have the same (and not merely compatible) types. Section 6.7.3.4 "Tags" Paragraph 1 N3220 I don't see anything that would require a conversion to int here, nor would I expect this to be the intent. It should just have the same value and the type will end up the same as in the previous declaration. > enum E { a = 1L, b = 2 }; > enum E { a = 1L, b = _Generic(a, enum E: 2) }; /* { dg-warning "outside the > range" } */ This just seems to be testing if int is compatible with enum E. Which from testing on godbolt is false on GCC since it would pick for enum E to be compatible with unsigned. This test also doesn't seem related to the problem which was having the types of the integral constant expressions for a be different types.
[Bug c/115109] New: Incorrect type of enumeration constant in redeclaration of enumeration constant (C23)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115109 Bug ID: 115109 Summary: Incorrect type of enumeration constant in redeclaration of enumeration constant (C23) Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: luigighiron at gmail dot com Target Milestone: --- GCC does not accept the following code: static_assert(INT_WIDTH<42&_WIDTH>=42); enum E{a=1UL<<40,b=1}; enum E{a=1ULL<<40,b=_Generic(a,unsigned long:1,default:2)}; The static_assert is there to document the assumptions that should make this code valid. Here is the relevant part of the standard: > During the processing of each enumeration constant in the enumerator list, > the type of the enumeration constant shall be: > > - the previously declared type, if it is a redeclaration of the same > enumeration constant; or, > > - the enumerated type, for an enumeration with fixed underlying type; or, > > - int, if there are no previous enumeration constants in the enumerator list > and no explicit = with a defining integer constant expression; or, > > - int, if given explicitly with = and the value of the integer constant > expression is representable by an int; or, > > - the type of the integer constant expression, if given explicitly with = and > if the value of the integer constant expression is not representable by int; > or, > > ... Section 6.7.3.3 "Enumeration specifiers" Paragraph 12 N3220 The types of the enumeration constants 'a' and 'b' in the first enumeration specifier should be unsigned long and int, respectively. Then in the second enumeration declaration, they should have the same types as the first enumeration declaration because of the first item in the list in the above quote. GCC does not seem to follow this and makes the type of the enumeration constant 'a' unsigned long long because the type of the expression is unsigned long long.
[Bug c/114873] Incorrect warning generated for [*] array when in atomic or typeof type specifier for a parameter declaration
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114873 --- Comment #5 from Halalaluyafail3 --- (In reply to Joseph S. Myers from comment #4) > These are not meant to be valid C (although the relevant requirement isn't a > Constraint, so a diagnostic isn't required); see the discussion in DR#341. I thought these declarations were supposed to be valid since there doesn't seem to be anything forbidding them (unless I misunderstood the text "part of the nested sequence of declarators or abstract declarators for a parameter declaration") and they seemed to make sense to me. I did see DR#341 before making this bug report, and I assumed that it was specifically referring to the case of [*] in array sizes. Thanks for making the intent clear. I have recently thought about this again and realized that there may be an alternative way of doing this: void foo(typeof(int(*)[(0,0)])(*)[*]); void bar(_Atomic(int(*)[(0,0)])(*)[*]); It looks correct as (0,0) is not an integer constant expression and the array type isn't [*]. GCC and Clang seem to accept this without complaint as well (haven't tested other compilers). However the current wording says: > If the size is an expression that is not an integer constant expression: > if it occurs in a declaration at function prototype scope, it is treated > as if it were replaced by *; otherwise, each time it is evaluated it shall > have a value greater than zero. Section 6.7.7.3 "Array declarators" Paragraph 5 N3220 This wording seems to say that the expression (0,0) would be replaced by * which would make the program invalid? Or perhaps it means that the type gets adjusted in the parameter declaration itself so that this is valid. The wording doesn't seem very clear here, though if it was the former approach then the following declarations would be invalid: //the type names in typeof and sizeof have function prototype scope void baz(size_t x,typeof(int[x])*y); void qux(size_t x,int(*y)[sizeof(char[x])]); Which seems unintended. I think this text should be updated to state how * replacement happens in cases like these. It also isn't clear what would happen in a declaration like the following: int a=1; typedef int b[a];//VLA outside of function prototype scope void(*c)(b*);//then used in function prototype scope This would depend upon whether 'it' refers to where the size expression is, or to where the type is used and then gets adjusted.
[Bug c/114873] Incorrect warning generated for [*] array when in atomic or typeof type specifier for a parameter declaration
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114873 --- Comment #3 from Halalaluyafail3 --- (In reply to Andrew Pinski from comment #1) > clang errors out: > :3:24: error: star modifier used outside of function prototype > 3 | void bar(_Atomic(int(*)[*])(*)[*]); > |^ > :3:30: error: a type specifier is required for all declarations > 3 | void bar(_Atomic(int(*)[*])(*)[*]); > | ^ I made a bug report for Clang earlier today about this: https://github.com/llvm/llvm-project/issues/90348.
[Bug c/114873] New: Incorrect warning generated for [*] array when in atomic or typeof type specifier for a parameter declaration
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114873 Bug ID: 114873 Summary: Incorrect warning generated for [*] array when in atomic or typeof type specifier for a parameter declaration Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: luigighiron at gmail dot com Target Milestone: --- GCC generates warnings for [*] arrays when in an atomic or type specifier even if it is part of a parameter declaration for example: void foo(typeof(int(*)[*])(*)[*]); void bar(_Atomic(int(*)[*])(*)[*]); These generate warnings (saying that '[*]' not in a declaration) when they should be fine. They should be equivalent to: void foo(int(*(*)[*])[*]); void bar(int(*_Atomic(*)[*])[*]); Which generate no warnings.
[Bug c++/114857] New: Pointer attributes and qualifiers are parsed in wrong order
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114857 Bug ID: 114857 Summary: Pointer attributes and qualifiers are parsed in wrong order Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: luigighiron at gmail dot com Target Milestone: --- GCC accepts the following declaration: int*const[[]]p=0; And rejects the following declaration: int*[[]]const p=0; It seems that GCC expects the attributes of a pointer declarator to come after the qualifiers. The standard specifies in the grammar that the attributes should come before qualifiers and not after: > ptr-operator: > * attribute-specifier-seq opt cv-qualifier-seq opt > & attribute-specifier-seq opt > && attribute-specifier-seq opt > nested-name-specifier * attribute-specifier-seq opt cv-qualifier-seq opt Section 9.3.1 "General" [dcl.decl.general] Paragraph 5 ISO/IEC 14882:2020 The first declaration should be rejected and the second declaration should be accepted. Clang and MSVC get this correct (though not EDG I think so Visual Studio will show errors in the correct declarations and not in the incorrect declarations), and GCC gets this correct with pointer to members but not with normal pointers.
[Bug c/114723] ICE when checking for type compatibility with structure that contains flexible array member (C23)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114723 --- Comment #6 from Halalaluyafail3 --- (In reply to Andrew Pinski from comment #4) > Oh this is with `-g -std=c23`, godbolt has an implicit -g. I was not aware of this, thanks for letting me know. Do you know of any way to disable it? Also it does seem to be quite related, so it is probably the same bug which caused an ICE here (though the context of that test case would require the types be the same so it's a little bit different).
[Bug c/114723] ICE when checking for type compatibility with structure that contains flexible array member (C23)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114723 --- Comment #3 from Halalaluyafail3 --- Just tested on godbolt again and it cause an ICE, so perhaps something was changed to cause an ICE again. Also upon thinking about the implications of these types being compatible they probably shouldn't be compatible and it's either a defect in the standard or I missed something that would make these types incompatible.
[Bug c/114816] New: Non-standard behavior with void arguments
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114816 Bug ID: 114816 Summary: Non-standard behavior with void arguments Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: luigighiron at gmail dot com Target Milestone: --- After thinking about qualified void return types I decided to think about void function parameters: > The special case of an unnamed parameter of type void as the only item in > the list specifies that the function has no parameters. Section 6.7.6.3 "Function declarators (including prototypes)" Paragraph 10 ISO/IEC 9899:2018 No other restrictions are present that would forbid void parameter types. GCC seems to accept functions that use such arguments as long as they have names, for example: void a(void x); void b(const void x,register void y,register volatile void z); Are accepted by GCC, but the following declarations are not accepted by GCC when they should be valid: void c(void,void); void d(const void); Other incomplete types are accepted by GCC. Note that the type of the parameter is const void and not void so d is a function taking an argument of type const void and returning void, which means that the types of a and d are compatible. The storage class register can be used on arguments and the same is true for void arguments, which doesn't affect the type so the following program should be valid: int main(register void){} Clang accepts this while GCC rejects. The storage class register doesn't affect the type and it is still one unnamed parameter of type void so this should be a declaration for zero arguments. Calling any function with a void parameter is a constraint violation because of the following contraint: > If the expression that denotes the called function has a type that includes > a prototype, the number of arguments shall agree with the number of > parameters. Each argument shall have a type such that its value may be > assigned to an object with the unqualified version of the type of its > corresponding parameter. Section 6.5.2.2 "Function calls" Paragraph 2 ISO/IEC 9899:2018 GCC does not diagnose the error and instead just interprets the first void argument as being a sentinel value indicating when the arguments end, for example with the function a from before GCC accepts calling it with zero arguments. Qualified versions of void for example with the function b from before are properly diagnosed. When referencing a function type with a single void parameter GCC will omit the name of the parameter as usual which leads to some confusing error messages, for example: void f(void x); void f(void); The error message indicates that these types are incompatible, but it describes the first declaration as having type void(void). Here is the error output omitting source locations: > error: conflicting types for 'f'; have 'void(void)' > void f(void); > ^ > note: previous declaration of 'f' with type 'void(void)' > void f(void x); > ^
[Bug c/114808] Qualified void return type is not diagnosed
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114808 Halalaluyafail3 changed: What|Removed |Added Resolution|--- |FIXED Status|NEW |RESOLVED --- Comment #9 from Halalaluyafail3 --- Resolving since I feel that the current behavior here is correct after looking at the text in the standard enough. -Wignored-qualifiers also seems to cover this case so adding a new warning shouldn't be needed either.
[Bug c/114808] Qualified void return type is not diagnosed
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114808 --- Comment #6 from Halalaluyafail3 --- * Paragraph 5 instead of Paragraph 4
[Bug c/114808] Qualified void return type is not diagnosed
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114808 --- Comment #5 from Halalaluyafail3 --- I made this bug report because of the warning that clang has, but the following paragraph may allow this: > If, in the declaration "T D1", D1 has the form > D ( parameter-type-list ) > or > D ( identifier-list opt ) > and the type specified for ident in the declaration "T D" is > "derived-declarator-type-list T", then the type specified for > ident is "derived-declarator-type-list function returning the > unqualified version of T". Section 6.7.6.3 "Function declarators (including prototypes)" Paragraph 4 ISO/IEC 9899:2018 GCC seems to be using this to not make a diagnostic here, e.g. it warns with a return type of _Atomic void in C17 mode but not in C23 mode where the text here was updated to indicate that the result is the unqualified and non-atomic version of T. If this would make the text talking about the return type of the function refer to the unqualified return type then this should be allowed I think, and I will make a bug report to clang to get this diagnostic changed.
[Bug c/114808] New: Qualified void return type is not diagnosed
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114808 Bug ID: 114808 Summary: Qualified void return type is not diagnosed Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: luigighiron at gmail dot com Target Milestone: --- The following code is accepted in GCC with no diagnostics being produced (even when using -pedantic-errors): const void f(void){} This code violates the following constraint: > The return type of a function shall be void or a complete object type other > than array type. Section 6.9.1 "Function definitions" Paragraph 3 ISO/IEC 9899:2018 const void is not void and it is not a complete object type.
[Bug c/114723] ICE when checking for type compatibility with structure that contains flexible array member (C23)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114723 --- Comment #2 from Halalaluyafail3 --- (In reply to Richard Biener from comment #1) > This seems to be fixed recently? I just tested the code on godbolt again, and it doesn't seem to generate an ICE anymore. However, it does seem to generate "incompatible" which seems to be incorrect unless there is something that I missed in the standard which would make these types incompatible.
[Bug c/114723] New: ICE when checking for type compatibility with structure that contains flexible array member
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114723 Bug ID: 114723 Summary: ICE when checking for type compatibility with structure that contains flexible array member Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: luigighiron at gmail dot com Target Milestone: --- The following code causes an internal compiler error on GCC 14: #include struct S{int x,y[1];}*a; int main(void){ struct S{int x,y[];}; puts(_Generic( a, struct S*:"compatible", default:"incompatible" )); } If I understand the type compatibility rules, these types should be compatible? The types "int[1]" and "int[]" are compatible and everything else seems to match exactly. Interestingly, it seems to also crash when checking if the type of a is compatible with struct S (instead of struct S*).
[Bug libstdc++/114325] New: std::format gives incorrect results for negative numbers
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114325 Bug ID: 114325 Summary: std::format gives incorrect results for negative numbers Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: luigighiron at gmail dot com Target Milestone: --- The following code generates an incorrect result with libstdc++: std::format("{}",-100) >From testing on godbolt this seems to generate the string "-1\", then when printed it looks like -10. This seems exclusive to GCC 14, and happens for any numbers less than -99.
[Bug c++/114315] New: Attributes should be diagnosed when placed in the middle of declaration specifiers
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114315 Bug ID: 114315 Summary: Attributes should be diagnosed when placed in the middle of declaration specifiers Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: luigighiron at gmail dot com Target Milestone: --- GCC will accept programs that use attribute specifiers in the middle of declaration specifiers, for example: int[[]]signed main(){} Attribute specifiers are not allowed inside of the declaration specifiers. I would expect a warning or an error here, at least when -pedantic/-pedantic-errors. Here is a link to the grammar of declaration specifiers: https://eel.is/c++draft/dcl.spec.general#nt:decl-specifier-seq. The attribute specifier is required to be at the end of the declaration specifiers.
[Bug c++/113571] Preprocessor if directive does not correctly recognize all C++ integral constant expressions
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113571 --- Comment #3 from Halalaluyafail3 --- The way the standard is written doesn't make any distinction between a preprocessor constant expression and a language constant expression (from what I have seen). The standard just says integral constant expression, and this term is used both inside of the preprocessor and outside of the preprocessor; for example the value of an enumerator. I don't see anything in the standard would make the examples I provided invalid in a preprocessor if so I would expect them to be valid.
[Bug c++/113571] New: Preprocessor if directive does not correctly recognize all C++ integral constant expressions
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113571 Bug ID: 113571 Summary: Preprocessor if directive does not correctly recognize all C++ integral constant expressions Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: luigighiron at gmail dot com Target Milestone: --- When preprocessing C++ code, GCC interprets preprocessor if expressions using the same rules as C constant expressions. For example the following preprocessor if directives cause errors when they should be valid C++: #if(1,2) #endif #if 0?1.,2:3 #endif #if([]{}(),1)==1 #endif #if 0<=>0==0 #endif The C++ standard requires that the expression in a preprocessor if directive is an integer constant expression: > The expression that controls conditional inclusion shall be an integral > constant expression except that identifiers (including those lexically > identical to keywords) are interpreted as described below and it may contain > zero or more defined-macro-expressions and/or has-include-expressions and/or > has-attribute-expressions as unary operator expressions. Section 15.2 "Conditional inclusion" [cpp.cond] Paragraph 1 ISO/IEC 14882:2020 > An integral constant expression is an expression of integral or unscoped > enumeration type, implicitly converted to a prvalue, where the converted > expression is a core constant expression. Section 7.7 "Constant expressions" [expr.const] Paragraph 8 ISO/IEC 14882:2020 The way C++ describes preprocessor if expressions is equivalent to constant expressions outside of the preprocessor, so all of the examples listed in this bug report should be valid (GCC does correctly allow these expressions in other contexts, such as the value of an enumerator). These quotes were taken from N4868, so the paragraph numbers not might match exactly. The text in drafts after C++20 contain the same wording so they should be correct.
[Bug c/113011] New: main declared with enumerated type is not accepted
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113011 Bug ID: 113011 Summary: main declared with enumerated type is not accepted Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: luigighiron at gmail dot com Target Milestone: --- The following code is rejected in GCC with pedantic mode enabled: enum E{e=-1}; _Static_assert( _Generic((enum E)e,int:1,default:0), "incorrect enumeration type" ); enum E main(){} If the static assertion succeeds, then the type enum E is compatible with int. Given that enum E is compatible with int, it should be a valid return type of main: > If the return type of the main function is a type compatible with int, > a return from the initial call to the main function is equivalent to > calling the exit function with the value returned by the main function > as its argument; reaching the } that terminates the main function returns > a value of 0. If the return type is not compatible with int, the termination > status returned to the host environment is unspecified. Section 5.1.2.2.3 "Program termination" Paragraph 1 ISO/IEC 9899:2018 Additionally, here is the paragraph explaining that an enumerated type is compatible with its underlying type: > Each enumerated type shall be compatible with char, a signed integer type, > or an unsigned integer type. The choice of type is implementation-defined, > but shall be capable of representing the values of all the members of the > enumeration. Section 6.7.2.2 "Enumeration specifiers" Paragraph 4 ISO/IEC 9899:2018 Outside of pedantic mode, GCC accepts the code but returns a non-zero value when the closing brace is reached which isn't correct either.
[Bug c/112841] New: typeof_unqual is not removing qualifiers from array types
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112841 Bug ID: 112841 Summary: typeof_unqual is not removing qualifiers from array types Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: luigighiron at gmail dot com Target Milestone: --- GCC does not remove qualifiers from array types when used with typeof_unqual: puts(_Generic( (typeof_unqual(const int[])*)0, int(*)[]:"non-const", const int(*)[]:"const" )); This should print non-const, but GCC prints const. The latest working draft of the standard includes an example of typeof_unqual with an array of const: > EXAMPLE 2 The following program: > const _Atomic int purr = 0; > const int meow = 1; > const char* const animals[] = { > "aardvark", > "bluejay", > "catte", > }; > typeof_unqual(meow) main (int argc, char* argv[]) { > typeof_unqual(purr) plain_purr; > typeof(_Atomic typeof(meow)) atomic_meow; > typeof(animals) animals_array; > typeof_unqual(animals) animals2_array; > return 0; > } > is equivalent to this program: > const _Atomic int purr = 0; > const int meow = 1; > const char* const animals[] = { > "aardvark", > "bluejay", > "catte", > }; > int main (int argc, char* argv[]) { > int plain_purr; > const _Atomic int atomic_meow; > const char* const animals_array[3]; > const char* animals2_array[3]; > return 0; > } Section 6.7.2.5 "Typeof specifiers" Paragraph 7, from N3096 Here, GCC does not not remove the const on the array type for animals2_array in the first part of the example.
[Bug c++/112839] New: Unable to default initialize member variable in specific circumstances
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112839 Bug ID: 112839 Summary: Unable to default initialize member variable in specific circumstances Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: luigighiron at gmail dot com Target Milestone: --- The following code is not accepted by GCC: struct A { struct B { int C = 0; }; A() = default; A(int) {} std::pair p; }; The error message generated indicates that it was unable to find a constructor to call in the constructor A(int). Doing any of the following seems to remove the error: 1. Removing the constructor A() 2. Explicitly define the constructor A() 3. Defining a default constructor for B (that isn't defaulted) 4. Removing the default value from C 5. Initializing p when it is being declared, i.e. std::pair p{}; 6. Defining B outside of the class 7. Using a non-default constructor in the member initializer list Clang, MSVC, and old versions of GCC (version 8, version 5, and version 4) accept this code.
[Bug c/112556] Null pointer constants with enumeration type are not accepted
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112556 --- Comment #1 from Halalaluyafail3 --- This bug also seems to happen with boolean types: void*p=(_Bool)0; Furthermore, this bug only seems to happen when the type of the null pointer constant is an enumeration or boolean type: void*p1=+(_Bool)0,*p2=+(enum{E})E; No errors are generated for this code.
[Bug c/112556] New: Null pointer constants with enumeration type are not accepted
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112556 Bug ID: 112556 Summary: Null pointer constants with enumeration type are not accepted Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: luigighiron at gmail dot com Target Milestone: --- The following code is not accepted in GCC: void*p=(enum{E})E; To make it clear why this code should be accepted, I have provided some references to the current C standard. > An integer constant expression with the value 0, > or such an expression cast to type void *, is called > a null pointer constant. If a null pointer constant is > converted to a pointer type, the resulting pointer, > called a null pointer, is guaranteed to compare unequal > to a pointer to any object or function. Section 6.3.2.3 "Pointers" Paragraph 1 ISO/IEC 9899:2018 > 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. Section 6.6 "Constant expressions" Paragraph 6 ISO/IEC 9899:2018 > The type char, the signed and unsigned integer types, > and the enumerated types are collectively called > integer types. The integer and real floating types are > collectively called real types. > > Integer and floating types are collectively called > arithmetic types. Each arithmetic type belongs to > one type domain: the real type domain comprises the > real types, the complex type domain comprises the > complex types. Section 6.2.5 "Types" Paragraphs 17 and 18 ISO/IEC 9899:2018 (enum{E})E is an integer constant expression because E is an enumeration constant, and the cast is converting an arithmetic type (int) to an integer type (the enumeration type). This integer constant expression has the value zero, so it is a null pointer constant. This problem seems to be specific to null pointer constants, for example the type int(*)[(enum{A,B})B] is not considered to be a variable length array type (which is correct).