"Heitber Andrés Montilla Ramirez" <montillaramirezh@gmail.com>: Oct 26 06:24PM -0700
Hi everyone I want to know why this error apperars to my code, I'm trying to do an OpenGL App Using codeblocks, I re-checked the code twice with the original tutorial and everything is ok. now the compiler throws the following error: |error: invalid conversion from 'const void*' to 'HANDLE {aka void*}' [-fpermissive]| I want your help to solve this issue. #define GLUT_DISABLE_ATEXIT_HACK #define GLEW_STATIC #if defined(_WIN32) || defined(_WIN64) #include <windows.h>
Manfred <noname@add.invalid>: Oct 26 05:15PM +0200
On 10/25/2021 8:11 PM, Keith Thompson wrote: > I don't see how the omission of "upon use of a nonportable or erroneous > program construct or of erroneous data" in the C++ standard makes any > real difference. It depends on the reader: whether it is some sort of text processing machine, a language lawyer or a human being. > In all cases, "undefined behavior" is determined either by an explicit > statement or by the omission of any definition of the behavior (or, in > C, by violation of a "shall" outside a constraint). For a human being, the additional sentence makes a difference, simply because it is there: it means that the writer had a reason to write it, and such writer's intent is part of the message that matters to a human reader. More specifically: In C, the additional sentence actually poses a distinctive characterization of the code that qualifies for undefined behavior, i.e. "nonportable or erroneus" code, which is something else than saying "anything that is not explicitly defined here". Now, the problem is that the C definition actually redirects to a definition of "nonportable" and (more relevantly) "erroneous", so a machine reader might trigger an "undefined reference" error and stop parsing. A language lawyer might interpret the wording as implying that anything that is not explicitly defined is considered "nonportable" or "erroneous", but that's an interpretation which is still to be proven to hold in court, since the other party's lawyer might interpret the same wording as UB being <<anything that is "nonportable" or "erroneous" /and/ is not covered by this standard's requirements>> Schematically, one might think of the entire set of possible source code to be validated against the standard, and divide it into the subsets: 1) Explicitly defined valid code (e.g. syntax of declarations) 2) Explicitly defined invalid code (e.g. constraint violations) 3) Code which is not explicitly defined by 1) and 2) Ideally, for a perfect standard, subset 3) would be empty - i.e. to make a machine reader happy. In practice, standards are (luckily) written by humans, so there may be something left in subset 3). To me, the additional sentence is intended to give a rationale to discriminate which is which in this area. That said, lawyers may still complain that a non-empty subset 3) leads to ambiguity, and this may be a serious problem in court. Pre-C++11 C++ apparently tried to address this potential ambiguity by adding "such as", thus suggesting that the category of "nonportable" or "erroneous" code is meant to be an example of code for which the standard poses "no requirements". The wording may appear to suggest that subset 3) is meant to be included in subset 2), but the authors didn't feel brave enough to say this explicitly, and left the categories of "nonportable" and "erroneous" in. The fact is that, obviously, placing subset 3) into subset 2) poses a heavy burden on the standard itself. C++11-and-later C++ was actually brave enough to assert that anything that is not explicitly defined in the standard is "undefined behavior", which would just be a self-identity assertion if it weren't for the note that clarifies that UB is a very Bad Thing™, unless such behavior is actually defined by the implementation. The result is that the latest C++ definition of UB is so strong that it suddenly raised the bar of the Standard's quality requirement by several levels, thus opening the Pandora's box of countless examples of UB that affect nowadays' C++, to the point of invalidating even sample code in Bjarne's TC++PL that has been valid since the beginning of time, and led to cryptic additions to the standard itself (std::launder, anyone?) This might be seen as a process of improvement of the language, but so far this seems controversial. | RacingRabbit@watershipdown.co.uk: Oct 26 03:21PM
On Tue, 26 Oct 2021 10:43:09 -0400 >> return 0; >> } >You shouldn't get a bus error this time. Do you understand why? Noooo! Really?? Have you actually read anything I wrote or are you just jumping on the bandwagon of what others have said in order to try and sound clever? | James Kuyper <jameskuyper@alumni.caltech.edu>: Oct 26 11:22AM -0400
>> with read-only memory. Within the scope of an identifier that identifies > No I'm not. The pointer will be pointing to a string literal in the program > static text area which is usually non modifiable. Yes, I discussed that fact, which is the real reason for the bus error you saw. It was not because you used * rather than [] in your declaration of str. >> Exception 1: it's not permitted to declare functions that take arrays as >> arguments, > Since when? Since K&R C. As explained below, the following is NOT a counter example. > void func(int a[2][3]) > { > printf("%d\n",a[1][2]); "A declaration of a parameter as "array of type" shall be adjusted to "qualified pointer to type", where the type qualifiers (if any) are those specified within the [ and ] of the array type derivation." (6.7.63.p6). There's an easy way you can test this. Declare func a second time, as follows: void func(int (*a)[3]); Such redeclaration is permitted only if the new declaration is compatible with the previous one. The "adjustment" described above makes your declaration identical to the second one. > int a[2][3]; > a[1][2] = 123; > func(a); Appearances to the contrary notwithstanding, that code does NOT pass the entire array a to func(). That's because: "Except when it is the operand of the sizeof operator, or the unary & operator, or is a string literal used to initialize an array, an expression that has type "array of type" is converted to an expression with type "pointer to type" that points to the initial element of the array object and is not an lvalue." (6.3.2p3). In the expression func(a), "a" is not the operand of the sizeof operator or the unary & operator, and it is certainly not a string literal. Therefore, a gets converted to &a[0]. Try it, add the following line to your program: func(&a[0]); It won't be diagnosed as an error, because &a[0] is a pointer to an array of 3 ints, which precisely what the first argument of func() has been declared to be (after the adjustments described above). It will simply result in a second printing of "123". > } > fenris$ cc t.c; a.out > 123 Neither of these features are new, they both date back to K&R C. | RacingRabbit@watershipdown.co.uk: Oct 26 03:26PM
On Tue, 26 Oct 2021 15:55:38 +0100 >I actually listed the 7 compilers I tried it on, just at the point where >you must have stopped reading. >Oh, you mean you only tried it on one implementation? Sorry, I have limited tolerance for smart asses so yes, I stopped reading. They're all toy compilers apart from VC and I specifically was talking about *nix and yes, these days that means gcc or clang. | James Kuyper <jameskuyper@alumni.caltech.edu>: Oct 26 11:27AM -0400
>> This shows ABC the first time it's executed. The second time it shows >> ZBC; the code has changed the string literal! Where the same literal iS > I suggest you actually try running that code and see what happens. The behavior of the code shown is undefined, and therefore very well might be exactly as he described - you would need to know precisely which compiler he used, on which platform, with which compiler options. That is in fact common behavior for such code. He claims that he did test it, and I know of no reason to disbelieve him. | RacingRabbit@watershipdown.co.uk: Oct 26 03:30PM
On Tue, 26 Oct 2021 11:22:18 -0400 >Yes, I discussed that fact, which is the real reason for the bus error >you saw. It was not because you used * rather than [] in your >declaration of str. Hello, we speak English on this group. Do. You. Understand. It? >>> arguments, >> Since when? >Since K&R C. As explained below, the following is NOT a counter example. Thats exactly what it is. Too bad it made you look stupid. >There's an easy way you can test this. Declare func a second time, as >follows: >void func(int (*a)[3]); [hopeless effort at self justification] You said arrays couldn't be declared as parameters. I showed you they could, end of. What the compiler does with it under the hood is irrelevant. tl;dr | James Kuyper <jameskuyper@alumni.caltech.edu>: Oct 26 11:52AM -0400
> On Tue, 26 Oct 2021 10:42:24 -0400 > James Kuyper <jameskuyper@alumni.caltech.edu> wrote: ... >> modifiable, but that's not just because of the "*", it's because str has >> been initialized to point at the first character of a string literal. It > So you disagree with what I said then say exactly the same thing yourself. You said that "[] means modifyable, * means read only in every C implementation I've ever used." That is false. What I said corresponds to the following examples: char array1[] = "modifiable"; const char array2[] = "optionally read only"; char *pointer1 = array1; const char *pointer2 = array1; array1[0] = 'u'; // permitted array2[0] = 'u'; // constraint violation *pointer1 = 'u'; // permitted *pointer2 = 'u'; // constraint violation pointer1 = "optionally read only"; // permitted *pointer1 = 'u'; // undefined behavior pointer2 = array2; *pointer2 = 'u'; // Still a constraint violation. Despite both of them being declared with [], and therefore according to you both being modifiable, array1 is modifiable, while array2 may be placed in read-only memory - but it doesn't have to be. Despite being declared with *, and therefore according to you being read-only, pointer1 points at modifiable memory the first time it is dereferenced, and points at memory that could be read-only the second time it is dereferenced. Despite being declared with *, pointer2 differs from pointer 1 in that it is always a constraint violation to write through it, regardless of whether or not it points at read-only memory. Despite being both declared with *, and therefore according to you being read-only, pointer1 and pointer2 are themselves modifiable, as shown by the fact that I changed both of their values. | James Kuyper <jameskuyper@alumni.caltech.edu>: Oct 26 12:23PM -0400
> On Tue, 26 Oct 2021 11:22:18 -0400 > James Kuyper <jameskuyper@alumni.caltech.edu> wrote: ... >> There's an easy way you can test this. Declare func a second time, as >> follows: >> void func(int (*a)[3]); Did you try inserting such a line? What were the results? > [hopeless effort at self justification] > You said arrays couldn't be declared as parameters. No, I said "it's not permitted to declare functions that take arrays as arguments, but it is permitted to declare a function parameter as if it were an array." Such a declaration does NOT declare the parameter to be an array, it declares it to be a pointer. You've retained my citation of the part of the standard that says so above. Here's a complete compilable program demonstrating that rule: #include <stdio.h> static void func(int a[2][3]) { printf("%s\n", _Generic(a, int[2][3]: "array", int(*)[3]: "pointer")); } int main(void) { int a[2][3]; func(a); } When I run that program, it says "pointer". What do you get when you run it? | Keith Thompson <Keith.S.Thompson+u@gmail.com>: Oct 26 09:49AM -0700
> On 26/10/2021 14:29, Ben Bacarisse wrote: >> Bart <bc@freeuk.com> writes: [...] >> permitted in C++. > I tried it in C++ before posting (as I'd thought that "ABC" would have > type const char*) but it seemed to work. (Using -Wall -std=c++14.) And you didn't bother to mention the diagnostic? I get warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings] And of course with "-pedantic-errors" it becomes a fatal error. Did you not get a diagnostic? It's not all that interesting to see what you can get away with by ignoring warnings. > I'm writing about what is typically observed. What I typically observe is that skilled programmers pay attention to warnings and do not attempt to modify string literals. > got round to it yet. > It is surprising that a big compiler like MSVC doesn't do so either, > but apparently that's only done when optimising; rather odd.) My quick experiment with MSVC 2017 does not confirm that. char *s = "ABC"; gives a fatal error in C++. It compiles in C (as expected), but attempting to modify the literal causes a run-time crash. -- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com Working, but not speaking, for Philips void Void(void) { Void(); } /* The recursive call of the void */ | James Kuyper <jameskuyper@alumni.caltech.edu>: Oct 26 12:51PM -0400
On 10/26/21 12:23 PM, James Kuyper wrote: ... > { > printf("%s\n", > _Generic(a, int[2][3]: "array", int(*)[3]: "pointer"));]]][ Here's another test you can perform. If that declaration declares a to be an array, the following assignment statement, inserted in the body of func(), should be a constraint violation: int b[4][3]; a = b; The left side of an assignment cannot have array type. On my system, those lines compiled without generating any diagnostics. | Keith Thompson <Keith.S.Thompson+u@gmail.com>: Oct 26 10:22AM -0700
>>abysmal understanding of C, while believing you understand it better >>than others. > Says the preening fool. James is not a "preening fool". He's right. You have joined a forum many of whose participants are experts on the C programming language. You have made a number of incorrect statements about C, and you have shown an inappropriately condescending attitude while doing so. This is a great place to learn about C, and I sincerely hope you'll take advantage of the opportunity. My advice is to express less certainty about the statements you make, engage in discussion, and stop insulting people. >>modifiable, but that's not just because of the "*", it's because str has >>been initialized to point at the first character of a string literal. It > So you disagree with what I said then say exactly the same thing yourself. No, that's not what he did. The array is read-only because it's a string literal. You didn't say that. -- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com Working, but not speaking, for Philips void Void(void) { Void(); } /* The recursive call of the void */ | Keith Thompson <Keith.S.Thompson+u@gmail.com>: Oct 26 10:27AM -0700
Keith Thompson <Keith.S.Thompson+u@gmail.com> writes: [...] > advantage of the opportunity. My advice is to express less certainty > about the statements you make, engage in discussion, and stop insulting > people. Sorry, I didn't notice which newsgroup I was in. C++, not C. (The rest of what I wrote stands.) [...] -- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com Working, but not speaking, for Philips void Void(void) { Void(); } /* The recursive call of the void */ | Bart <bc@freeuk.com>: Oct 26 06:38PM +0100
On 26/10/2021 17:49, Keith Thompson wrote: > And of course with "-pedantic-errors" it becomes a fatal error. > Did you not get a diagnostic? It's not all that interesting to see what > you can get away with by ignoring warnings. I used rextester.com, which uses the default options I used. There were no diagnostics. Maybe I could have tested half a dozen more C++ compilers, but they're thin on the ground on my machine. >> I'm writing about what is typically observed. > What I typically observe is that skilled programmers pay attention to > warnings and do not attempt to modify string literals. In general a compiler is not able to warn about the latter, and a programmer may not know that a pointer passed via a function for example points into readonly memory. Or out-of-bounds memory. Or contains NULL or other invalid memory address. It is however useful to know what might TYPICALLY happen if you do try and write into a string literal. | James Kuyper <jameskuyper@alumni.caltech.edu>: Oct 26 02:06PM -0400
On 10/26/21 1:27 PM, Keith Thompson wrote: >> people. > Sorry, I didn't notice which newsgroup I was in. C++, not C. (The > rest of what I wrote stands.) Even though this is comp.std.c++, and the original message was about C++, this sub-thread has turned into a discussion about C. However, everything we're saying about C is true of C++ as well (with some minor subtle differences), and everything he's saying incorrectly about C is incorrect for C++, too. The biggest difference in C++ would be that _Generic() is not supported, but typeinfo() is, which would actually be a more convenient of proving the truth of what we're saying. | Keith Thompson <Keith.S.Thompson+u@gmail.com>: Oct 26 11:20AM -0700
>> you can get away with by ignoring warnings. > I used rextester.com, which uses the default options I used. There > were no diagnostics. Yes, there were. rextester.com didn't show them to you because you didn't enable the "Show compiler warnings" checkbox. > Maybe I could have tested half a dozen more C++ compilers, but they're > thin on the ground on my machine. >>> I'm writing about what is typically observed. Any C++ compiler that does not issue a diagnostic for char* s = "ABC"; is non-conforming. I'm skeptical that there are very many C++ compilers out there that fail to do this when invoked properly. (C does not require a diagnostic, which makes it important to remember to add "const".) > programmer may not know that a pointer passed via a function for > example points into readonly memory. Or out-of-bounds memory. Or > contains NULL or other invalid memory address. In C++, it's difficult to even attempt to modify a string literal without either triggering a required diagnostic or explicitly doing something to override const. (It's easier in C, unfortunately.) > It is however useful to know what might TYPICALLY happen if you do try > and write into a string literal. Agreed. What typically happens in C++ is that you'll get a diagnostic before you even try to modify a string literal, since C++ string literals are const. What typically happens in C is that the program crashes. There are C compilers that don't put string literals in read-only memory (I've confirmed that tcc doesn't), but as far as I known none of them are in widespread use. -- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com Working, but not speaking, for Philips void Void(void) { Void(); } /* The recursive call of the void */ | "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Oct 26 11:20AM -0700
On 10/25/2021 12:45 PM, Chris M. Thomasson wrote: > self, I will get a nice warning. Its basically a habit of mine. 'self' > is akin to the this pointer in C++. > Oh well... ;^) See the deliberate mistake in here? Besides the foo_compute function returning int typo, argh!... Anyway, here is a program: ______________________________ #include <stdio.h> struct foo { unsigned int a; }; void foo_init( struct foo* const self, unsigned int a ){ self->a = a; } unsigned int foo_compute( struct foo const* const self, unsigned int a ){ return self->a *= a + 123; } int main() { struct foo foo; foo_init(&foo, 42); unsigned int foobar = foo_compute(&foo, 42); printf("foobar = %u\n", foobar); return 0; } ______________________________ Does not compile... GOOD! Change foo_compute to: ______________________________ unsigned int foo_compute( struct foo* const self, unsigned int a ){ return self->a *= a + 123; } ______________________________ and it does compile! So, const has it's uses, indeed. ;^) | James Kuyper <jameskuyper@alumni.caltech.edu>: Oct 26 02:34PM -0400
On 10/26/21 12:23 PM, James Kuyper wrote: ... > func(a); > } > When I run that program, it says "pointer". What do you get when you run it? Unfortunately, that doesn't prove what I intended it to prove, because even if a were an array, it would have been converted to a pointer when passed to _Generic. That problem is not too difficult to work around, I just have to use the '&' operator: #include <stdio.h> #define ARR_PTR(x) _Generic(&x, \ int(*)[2][3]: "array", \ int(**)[3]: "pointer", \ default: "other") static void func(int a[2][3]) { int b[2][3]; int (*c)[3]; printf("a:%s\n", ARR_PTR(a)); printf("b:%s\n", ARR_PTR(b)); printf("c:%s\n", ARR_PTR(c)); } int main(void) { int a[2][3]; func(a); } I get the following output: a:pointer b:array c:pointer What do you get? | Bart <bc@freeuk.com>: Oct 26 08:32PM +0100
On 26/10/2021 19:20, Keith Thompson wrote: >> were no diagnostics. > Yes, there were. rextester.com didn't show them to you because you > didn't enable the "Show compiler warnings" checkbox. How about that? A professional-looking site, which, by default, enables warnings for all those compilers and at the same time, by default, chooses to hide those warnings! | Bart <bc@freeuk.com>: Oct 26 08:35PM +0100
> Sorry, I have limited tolerance for smart asses Funny, that, so do I! So I'll leave you to it. | "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Oct 26 12:57PM -0700
On 10/26/2021 11:34 AM, James Kuyper wrote: > b:array > c:pointer > What do you get? Fwiw, I get the same: a:pointer b:array c:pointer :^) | David Brown <david.brown@hesbynett.no>: Oct 26 10:18PM +0200
On 26/10/2021 21:32, Bart wrote: > How about that? A professional-looking site, which, by default, enables > warnings for all those compilers and at the same time, by default, > chooses to hide those warnings! When it comes to websites, "professional-looking" is not a good indication of quality. I can't say much about that website, as I have no experience with it, but any professional programmer who doesn't enable warnings and pay attention to them should be looking for another career. (Of course the exact choice of warnings, and appropriate ways to handle them can vary by programmer style, project, and other factors. Hiding them all, however, is never appropriate.) I recommend <https://gotbolt.org> as having a wide selection of compilers, and showing generated code in a helpful format. (I haven't made a survey of alternatives and would be happy to hear of comparisons if someone has a suggestion that is better than godbolt.) | David Brown <david.brown@hesbynett.no>: Oct 26 10:32PM +0200
> Noooo! Really?? > Have you actually read anything I wrote or are you just jumping on the > bandwagon of what others have said in order to try and sound clever? Rabbit, I believe you are missing a few key points here. James is not trying to /sound/ clever - he /is/ clever. He is one of the top people in this group in terms of his knowledge and experience of C and C++, his accuracy in his explanations, and his patience in helping people. (There are others here with a similar level of respect and reputation, whom you have also insulted and disregarded.) A second key point is that you are wrong about almost everything you have been writing in this group - so wrong, that you don't even understand the question. You'd do well to stop being such an annoying little brat and listen to the people who are spending time and effort trying to help you understand the language a little better. (And yes, I know you'll respond to this with insults - I'm old enough not to be bothered about what some silly teenager thinks of me. But I am also naïve enough to think that not even you are beyond hope.) | Keith Thompson <Keith.S.Thompson+u@gmail.com>: Oct 25 11:11AM -0700
> program construct or of erroneous data" actually relegates the > language at the mercy of language lawyers, and led to the UB bloat > that affects C++ nowadays. [...] I don't see how the omission of "upon use of a nonportable or erroneous program construct or of erroneous data" in the C++ standard makes any real difference. C definition, all standard editions: behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this International Standard imposes no requirements C++ definition, before C++11: behavior, such as might arise upon use of an erroneous program construct or erroneous data, for which this International Standard imposes no requirement C++ definition, C++11 and later: behavior for which this International Standard imposes no requirements In all cases, "undefined behavior" is determined either by an explicit statement or by the omission of any definition of the behavior (or, in C, by violation of a "shall" outside a constraint). -- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com Working, but not speaking, for Philips void Void(void) { Void(); } /* The recursive call of the void */ | Lynn McGuire <lynnmcguire5@gmail.com>: Oct 26 03:55PM -0500
"C++ Smart Pointers and Arrays" by Bartlomiej Filipek https://www.cppstories.com/2021/smartptr-array/ "Smart pointers are very versatile and can hold pointers not only to single instances but also to arrays. Is that only a theoretical use case? or maybe they might be handy in some cases? Let's have a look." Lynn |
|