- I think references should have been const by default - 23 Updates
- C++ invalid conversion - 2 Updates
| Juha Nieminen <nospam@thanks.invalid>: Oct 27 04:43AM > 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. If gcc (or whichever compiler this is) doesn't give an outright error from trying to assign a const pointer to a non-const one without an explicit cast, then it's non-standard-conforming and I would classify it as a defect in the compiler. I think that the compiler should be fully standard-conforming by default, and be more permissive and have non-standard extensions and behavior only when explicitly specified using command-line parameters. Not the other way around. |
| Juha Nieminen <nospam@thanks.invalid>: Oct 27 04:44AM > Sorry, I have limited tolerance for smart asses so yes, I stopped reading. Then why are you responding? |
| Juha Nieminen <nospam@thanks.invalid>: Oct 27 04:57AM > [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. You seem to be confusing pointers with arrays. Which is not completely unexpected given that this confusing is very common among less experienced C (and C++) programmers, as the language makes that distinction oftentimes hard to discern. (I know that you will not read past this, but I'm going to try to explain it anyway.) An array and a pointer are not the same thing, not even in C. While an array can often be confused with a pointer, because an array almost always implicitly converts to a pointer-to-its-fist-element implicitly whenever one is needed, they are not the same thing. The most prominent situation where this distinction is made is when using the sizeof operator. The sizeof of a pointer will be just the size of the pointer itself (typically 4 or 8). The sizeof of an array will be the entire amount of bytes that the array takes. uint32_t values[10]; uint32_t *ptr = values; sizeof(values); // will be 40. sizeof(ptr); // will typically be 4 or 8. In C, and C++, you cannot pass arrays by value to a function as-is. You can only pass a pointer to an array. (This pointer will carry no information about the number of elements in the array, even if you use the confusing syntax where it looks like it does.) The only way you can pass an array to a function by value (both in C and C++) is by enclosing it inside a struct (or class) and passing an object of that type by value: struct MyArray { int values[10]; }; // Genuinely gets the entire array by value, not just a pointer: void foo(struct MyArray theArray); You can use the array syntax in a function parameter declaration, but that's just confusing syntax sugar: // It does not get an array of 10 elements by value, it's just // getting a pointer. The "10" in the declaration is meaningless: void foo(int values[10]) { printf("%u\n", sizeof(values)); // will print 4 or 8, not 40 } Honestly, I think it was a bad idea to add that syntactic sugar to C. It only causes confusion for no benefit. |
| Juha Nieminen <nospam@thanks.invalid>: Oct 27 05:01AM >>> Bus error: 10 >>For starters, that's in no way guaranteed to happen. Learn standard C. > It is on *nix and thats good enough for me. I would like a citation to the Single Unix Specification, or to POSIX, that states so. (I'm not saying it's not there. I just find it doubtful because not all CPU architectures have support for that.) >>Secondly, if you think that a runtime diagnostic is as good as a compile-time >>diagnostic, then you have still a LOT to learn about software development. > All I'm saying is the bug would exhibit itself pretty quickly. Then you are very inexperienced in software development. |
| Juha Nieminen <nospam@thanks.invalid>: Oct 27 05:04AM > 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? Actually he has. He read your assertion that "[] means modifiable and * means non-modifiable", and is proving you wrong: * can be perfectly well modifiable. Of course you will never acknowledge this. Instead you'll just start dodging with insults. |
| David Brown <david.brown@hesbynett.no>: Oct 27 08:29AM +0200 On 27/10/2021 06:43, Juha Nieminen wrote: > trying to assign a const pointer to a non-const one without an explicit > cast, then it's non-standard-conforming and I would classify it as a > defect in the compiler. You may /prefer/ an error (stopping compilation) rather than a warning, but the standard does not require it. A diagnostic message is all that is needed on constraint errors. I guess someone decided that a warning (always enabled, without requiring any flags) is a good compromise for the convenience of people converting old C code to C++. (I personally would prefer a hard error on this and many other faults in code, requiring particular options to allow people to compile questionable code. But backwards compatibility applies to build systems as well - there is a strong feeling that where possible, code that could be compiled with particular flags before should continue to be compilable.) It's the website rextester.com that is at fault in hiding warnings by default. That is idiotic, IMHO. > and be more permissive and have non-standard extensions and behavior only > when explicitly specified using command-line parameters. Not the other > way around. In this respect, gcc /is/ fully conforming. From C++14, 1.4p2 "Implementation compliance" """ If a program contains a violation of any diagnosable rule or an occurrence of a construct described in this Standard as "conditionally-supported" when the implementation does not support that construct, a conforming implementation shall issue at least one diagnostic message. """ |
| RacingRabbit@watershipdown.co.uk: Oct 27 07:57AM On Tue, 26 Oct 2021 12:23:37 -0400 >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." There is no difference. As I said, what the compiler does with it under the hood is not the point. The syntax declares an array. >When I run that program, it says "pointer". What do you get when you run it? Same. Not the point, its declared as an array. |
| Juha Nieminen <nospam@thanks.invalid>: Oct 27 08:47AM >>were an array." > There is no difference. As I said, what the compiler does with it under the > hood is not the point. The syntax declares an array. No, it doesn't. It declares a pointer. What do you think this will print? #include <stdio.h> void foo(int array[10]) { printf("foo: sizeof(array) = %lu\n", sizeof(array)); } int main() { int array[10]; int *ptr = array; printf("main: sizeof(array) = %lu\n", sizeof(array)); printf("main: sizeof(ptr) = %lu\n", sizeof(ptr)); foo(array); } |
| David Brown <david.brown@hesbynett.no>: Oct 27 11:07AM +0200 > hood is not the point. The syntax declares an array. >> When I run that program, it says "pointer". What do you get when you run it? > Same. Not the point, its declared as an array. Do you have trouble understanding the difference between an array, and a pointer to the first element of the array? C arrays are /never/ passed to functions as parameters, nor are they used directly in most expressions. (You can pass a struct that contains an array as a field, but that's a struct, not an array.) It is a major inconsistency in the type system of C, but one that works well in practice. Do you know the difference between : int ar1[10]; and std::array<int, 10> ar2; and how these may be passed to functions? |
| JohnnyCameLater@whatsthetime.net: Oct 27 02:29PM On Wed, 27 Oct 2021 08:47:42 -0000 (UTC) >> There is no difference. As I said, what the compiler does with it under the >> hood is not the point. The syntax declares an array. >No, it doesn't. It declares a pointer. What do you think this will print? Which parts of "syntax" and "under the hood" is confusing you. Perhaps in your own language? "syntaksi" "konepellin alla" Any clearer? |
| JohnnyCameLater@whatsthetime.net: Oct 27 02:30PM On Wed, 27 Oct 2021 11:07:03 +0200 >> Same. Not the point, its declared as an array. >Do you have trouble understanding the difference between an array, and a >pointer to the first element of the array? Do you have trouble understanding plain English? The syntax declares an array, the fact the compiler converts that into a pointer isn't the point. Pun intended. |
| David Brown <david.brown@hesbynett.no>: Oct 27 05:30PM +0200 > Do you have trouble understanding plain English? The syntax declares an array, > the fact the compiler converts that into a pointer isn't the point. Pun > intended. I don't know whether you are trolling, or if you are simply so arrogant that you would rather stay ignorant and insult people than admit to making a mistake and appreciate the help and advice you are given. Either way, feel free to come back with questions once you have grown up a little, and feel free to stay away until that day. |
| James Kuyper <jameskuyper@alumni.caltech.edu>: Oct 27 11:38AM -0400 >> were an array." > There is no difference. As I said, what the compiler does with it under the > hood is not the point. The syntax declares an array. The syntax uses [] rather than *. The semantics are those of a pointer, not an array. The semantics are NOT "under the hood" - they restrict what you can do with the function without violating a constraint. They determine what result you get when you apply the sizeof() or unary & operators to the parameter. Most importantly, they determine what happens if you write expressions such as "parameter[1] = 5". Getting back to my original statement, declaring a parameter with pointer semantics using the [] syntax does not allow you to pass an array as the corresponding argument in the function call. All you can pass is a pointer to the first element of the array - which is what any lvalue of array type will be converted into if passed as an argument to such a function. Since C uses "pass by value" exclusively, if you were able to pass an array as an argument, then the corresponding parameter would be a separate array object with a different address, initialized by copying from the array argument. Evaluation the expression "parameter[1] = 5" would only affect the parameter, it would have no effect on the array argument. You can get some idea of how C would behave if such declarations were possible, by declaring a struct type containing an array. Such a struct could be passed into or returned by a function by value. It's syntactically different from, but semantically equivalent to, passing around the array itself by value. The actual C semantics of such a function call are that the corresponding parameter is a separate pointer object filled in by copying the value of the pointer that the lvalue was converted to. Evaluating the expression "parameter[1] = 5" would set the second element of the array to 5. |
| James Kuyper <jameskuyper@alumni.caltech.edu>: Oct 27 11:39AM -0400 > On Wed, 27 Oct 2021 11:07:03 +0200 > David Brown <david.brown@hesbynett.no> wrote: ... > Do you have trouble understanding plain English? The syntax declares an array, > the fact the compiler converts that into a pointer isn't the point. Pun > intended. "array" vs. "pointer is a matter of semantics. [] vs * is a matter of syntax. All you can say about the syntax is that it contains []. In most contexts, [] in the syntax of a declaration corresponds to array semantics. However, the standard is quite explicit about the fact that, in this context, what [] means is pointer semantics. This is not just quibbling. It determine which arguments can be passed to the function without violating a constraint. Two function prototypes are compatible only if the type that one of them declares for a given parameter is compatible with the type declared by the other for that same parameter. If one function prototype uses "int array[]" for one parameter, and the other uses "* int pointer" for the same parameter, those two prototypes are compatible. |
| JohnnyCameLater@whatsthetime.net: Oct 27 03:46PM On Wed, 27 Oct 2021 17:30:43 +0200 >> the fact the compiler converts that into a pointer isn't the point. Pun >> intended. >I don't know whether you are trolling, or if you are simply so arrogant Pot -> kettle. >making a mistake and appreciate the help and advice you are given. >Either way, feel free to come back with questions once you have grown up >a little, and feel free to stay away until that day. Go fuck yourself you patronising jerk. |
| JohnnyCameLater@whatsthetime.net: Oct 27 03:49PM On Wed, 27 Oct 2021 11:38:54 -0400 >> hood is not the point. The syntax declares an array. >The syntax uses [] rather than *. The semantics are those of a pointer, >not an array. The syntax defines an array. Why do you think you get compiler warnings if you go OOB with an index value? Try it. >The semantics are NOT "under the hood" - they restrict what you can do Yes, they are. tl;dr |
| JohnnyCameLater@whatsthetime.net: Oct 27 03:51PM On Wed, 27 Oct 2021 11:39:16 -0400 >contexts, [] in the syntax of a declaration corresponds to array >semantics. However, the standard is quite explicit about the fact that, >in this context, what [] means is pointer semantics. Oh really? fenris$ cat t.c #include <stdio.h> void func(int a[2][3]) { a[10][50] = 123; } int main() { int a[2][3]; func(a); return 0; } fenris$ cc t.c t.c:5:2: warning: array index 50 is past the end of the array (which contains 3 elements) [-Warray-bounds] a[10][50] = 123; ^ ~~ t.c:3:11: note: array 'a' declared here void func(int a[2][3]) ^ 1 warning generated. Nuff said. |
| scott@slp53.sl.home (Scott Lurndal): Oct 27 04:13PM >On 27/10/2021 16:30, JohnnyCameLater@whatsthetime.net wrote: >>> On 27/10/2021 09:57, RacingRabbit@watershipdown.co.uk wrote: >I don't know whether you are trolling, Given the choice of nyms,and the name changes, my assumption has been trolling. Best to simply ignore such posts. |
| Ben Bacarisse <ben.usenet@bsb.me.uk>: Oct 27 05:21PM +0100 >>semantics. However, the standard is quite explicit about the fact that, >>in this context, what [] means is pointer semantics. > Oh really? Yes. > ^ > 1 warning generated. > Nuff said. Not really. Note that the compiler does not complain about the first index (10) being out of bounds. That's because (despite the badly worded note) it's only the three-element objects pointed to by 'a' that are in fact arrays with a known bound. Some compilers explain the issue more clearly. Here's gcc 11.2 giving much better, but identical, notes about these two functions: void func(int a[2][3]) { a[10][50] = 123; } void func2(int (*a)[3]) { a[10][50] = 123; } x.c: In function 'func': x.c:3:11: warning: array subscript 50 is above array bounds of 'int[3]' [-Warray-bounds] 3 | a[10][50] = 123; | ~~~~~^~~~ x.c:1:15: note: while referencing 'a' 1 | void func(int a[2][3]) | ~~~~^~~~~~~ x.c: In function 'func2': x.c:3:11: warning: array subscript 50 is above array bounds of 'int[3]' [-Warray-bounds] 3 | a[10][50] = 123; | ~~~~~^~~~ x.c:6:18: note: while referencing 'a' 6 | void func2(int (*a)[3]) | ~~~~~~^~~~~ -- Ben. |
| James Kuyper <jameskuyper@alumni.caltech.edu>: Oct 27 12:26PM -0400 > On Wed, 27 Oct 2021 11:39:16 -0400 > James Kuyper <jameskuyper@alumni.caltech.edu> wrote: ... >> semantics. However, the standard is quite explicit about the fact that, >> in this context, what [] means is pointer semantics. > Oh really? Yes, really. > void func(int a[2][3]) > ^ > 1 warning generated. The standard imposes no requirements on diagnostics - in particular, it does not require them to correctly describe the problem - many implementations occasionally generate incorrectly worded diagnostics, even when describing legitimate errors, and this warning is one example. The actual type of a is int(*)[3], not int[2][3], a fact that you can confirm using sizeof(a) or &a (the difference between those types disappears in all other contexts, due to the implicit array=>pointer conversion). This message is posted to C++. While C++ has many differences from C, this isn't one of them, and in C++ a more convenient way to check the type of a is to use typeid(a).name(). Unfortunately, the resulting string is implementation-defined - on my machine it is a coded version of the type, rather than a proper C++ type specification. However, if you declare int b(*)[3]; int c[2][3]; then you should find that typeid(a)==typeid(b), and typeid(a) != typeid(c). typeid(a).name() should be the same as typeid(b).name(), and both should be different from the typeid(c).name(). Let me know what you find when you try that. There is an array bounds violation in your code, but it's not in a itself, which is not an array. a is a pointer that can be used to point at any unqualified array with an element type of int[3], regardless of how large. However, whatever array you point a at, if a[10] refers to an actual element of that array, then a[10][50] violates the bounds of the 3-element array that a[10] points at, not the bounds of a itself, which has none. You'll get the same error if you change a[10][50] to a[1][50], and there wouldn't be any problem in func() itself if you changed it to a[10][2]. If you pass a pointer to func() which will still point at a different element of the same array after 10 is added to it, then a[10][2] inside of func() would also have defined behavior - which would be to change the corresponding element of the pointed-at array, rather than the corresponding element of a, which has none. |
| James Kuyper <jameskuyper@alumni.caltech.edu>: Oct 27 12:36PM -0400 > On Wed, 27 Oct 2021 11:38:54 -0400 > James Kuyper <jameskuyper@alumni.caltech.edu> wrote: >> On 10/27/21 3:57 AM, RacingRabbit@watershipdown.co.uk wrote: ... >> not an array. > The syntax defines an array. Why do you think you get compiler warnings if > you go OOB with an index value? Try it. I did try it, and I don't get a compiler warning if I violate the supposed leading dimension of that array, which is the dimension that gets "adjusted" into a pointer: static void func (int a[2][3]) { a[4][2] = 123; } int main(void) { int b[8][3] = 0; func(b); return b[4][2]; } Subscripting with a[i][j] with j>2 would be just as much of an array violation if the type of a is int(*)[3] as it would be if the type of a were int[2][3]. |
| Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Oct 27 05:41PM +0100 On Wed, 27 Oct 2021 11:07:03 +0200 > used directly in most expressions. (You can pass a struct that contains > an array as a field, but that's a struct, not an array.) It is a major > inconsistency in the type system of C, but one that works well in practice. I know what you mean - they are never passed by value as parameters - but they can be passed by reference as an array rather than as a pointer to their first element. In C++ you have this available: there is no pointer decay and it will print 10: void func (char (&arr)[10]) { std::cout << sizeof(arr) << std::endl; } int main() { char arr9[9]; char arr10[10]; // func(arr9); // won't compile func(arr10); // OK } In C and C++ you have this, which will also print 10: void func (char (*arr)[10]) { std::cout << sizeof(*arr) << std::endl; } int main() { char arr9[9]; char arr10[10]; // func(&arr9); // won't compile func(&arr10); // OK } None of this detracts from the fact that your nym-shifting correspondent is not only clueless but also unable to learn. |
| David Brown <david.brown@hesbynett.no>: Oct 27 07:02PM +0200 On 27/10/2021 18:41, Chris Vine wrote: > but they can be passed by reference as an array rather than as a pointer > to their first element. In C++ you have this available: there is no > pointer decay and it will print 10: You can do that in C++, not in C. References in C++ are basically the same concept as const pointers (as distinct from pointers to const), just with a slightly different syntax. Your "func" here is not taking an array as a value parameter (like C, you can't do that in C++ with plain arrays), nor is it using array syntax as a means of specifying a pointer to the first element. It is a pointer to an /array/. > void func (char (*arr)[10]) { > std::cout << sizeof(*arr) << std::endl; > } Yes, that is much the same as a reference in C++ (though you'd be slightly closer with "char (*arr)[10]" ). (I think that references are often better than pointers - they can be safer and clearer. But they are not fundamentally different, as can be seen by looking at implementations - they are convenient syntactic sugar.) > None of this detracts from the fact that your nym-shifting correspondent > is not only clueless but also unable to learn. Indeed. |
| "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>
Subscribe to:
Post Comments (Atom)
|
No comments:
Post a Comment