EmbeddedRelated.com
Forums

Dimension of a matrix

Started by Tim Wescott March 23, 2017
Am 25.03.2017 um 19:12 schrieb Les Cargill:
> David Brown wrote:
> I could not tell you which versions of which compilers support this, > but in some toolchains, it's possible to specify the size of an array > being passed - void p(char x[256])... .
All C compilers are actually required to allow you to pass a size like that. It doesn't have any effect whatsoever, though. Any number you put between those [] is really just decoration. These 4 function declarations are totally equivalent: void p(char x[256]); void p(char x[7]); void p(char x[]); void p(char *x);
Hans-Bernhard Bröker wrote:
> Am 25.03.2017 um 19:12 schrieb Les Cargill: >> David Brown wrote: > >> I could not tell you which versions of which compilers support this, >> but in some toolchains, it's possible to specify the size of an array >> being passed - void p(char x[256])... . > > All C compilers are actually required to allow you to pass a size like > that. It doesn't have any effect whatsoever, though. Any number you > put between those [] is really just decoration. These 4 function > declarations are totally equivalent: > > void p(char x[256]); > void p(char x[7]); > void p(char x[]); > void p(char *x); > >
I recall (vaguely) code where sizeof(x) would return 256, but it's a hazy memory. I don't remember the toolchain; probably latter day MS VS stuff. And even if it's just decoration, it preserves the size of the array out of band. -- Les Cargill
Wouter van Ooijen wrote:
> Op 24-Mar-17 om 00:17 schreef Tim Wescott: >> I just put the following into yet another c/c++ file: >> >> #define DIM(x) (sizeof(x) / sizeof(*x)) >> >> It calculates the number of elements in the array x (assuming that >> x is, indeed an array). >> >> Is there anything in the standard libraries that does this easy >> and obvious thing? > > Just for my curiosity, why would you want to do that? You don't need > it for iteration. > > Maybe to make a same-sized temporary array? But then it would make > sense to name the array type, and use that type. But maybe for a > same-sized array of a different element type. But I think I could > make a template to do that. > > And if you do need it, if the array declaration is in scope, I > assume that it was defined with some named literal dimension, so why > not used that? > > Wouter "Objects? No Thanks!" van Ooijen >
A pattern I use frequently is to declare a table of const data without giving it an extent, then have "const int lim = sizeof(table)/sizeof(table[0]);" for a loop invariant for table searches. For tables that grow, you'd need a "max" variable and then you'd need a definite limit. It's less fiddly than counting; you don't care what the limit is, just that the limit is known. -- Les Cargill
On Sat, 25 Mar 2017 11:07:30 -0500, Tim Wescott <tim@seemywebsite.com>
wrote:

>On Fri, 24 Mar 2017 23:14:36 -0400, George Neuner wrote: > >> On Fri, 24 Mar 2017 18:24:44 -0000 (UTC), Simon Clubley >> <clubley@remove_me.eisner.decus.org-Earth.UFP> wrote: >> >>>In the C++ library, it would be nice if the indexing operator most >>>people would use by default, "[]", was the bounds checked one and the >>>alternative indexing operator, "at()", was the non-bounds checked one. >>>That way, you would have to do something unusual in your code to turn >>>_off_ bounds checking instead of having to do something unusual in your >>>code to turn _on_ bounds checking... >> >> Agreed. However, that would violate the C/C++ mantra that those who do >> not want a feature should not have to pay for it. >> >> Strict bounds checking - particularly checks per dimension as opposed to >> a single check that the overall target lies within the array - would >> break some existing code. >> [For the same reasons that pointers may be one-of before or after the >> array, and iterators may be considered to point "between" elements.] > >We're talking about the C++ STL "array" class, which is defined as having >a certain size, with no guarantees about what lies outside the range of >the actual data.
Yes. But not every array in C++ uses the STL class, and I was reacting to Simon's comment about the '[]' index operator. It would be hopelessly confusing if the index operator of the array class was checked, but the general (C compatible) index operator was not. If the general operator were checked, undoubtedly some code would break, and even though STL arrays are heap allocated with some overrun slop, I suspect that checking the operator there also would break some existing code. [Not that breaking crappy code is a bad thing ... 8-) ] YMMV, George
Op 26-Mar-17 om 11:45 schreef George Neuner:
> On Sat, 25 Mar 2017 11:07:30 -0500, Tim Wescott <tim@seemywebsite.com> > wrote: > >> On Fri, 24 Mar 2017 23:14:36 -0400, George Neuner wrote: >> >>> On Fri, 24 Mar 2017 18:24:44 -0000 (UTC), Simon Clubley >>> <clubley@remove_me.eisner.decus.org-Earth.UFP> wrote: >>> >>>> In the C++ library, it would be nice if the indexing operator most >>>> people would use by default, "[]", was the bounds checked one and the >>>> alternative indexing operator, "at()", was the non-bounds checked one. >>>> That way, you would have to do something unusual in your code to turn >>>> _off_ bounds checking instead of having to do something unusual in your >>>> code to turn _on_ bounds checking... >>> >>> Agreed. However, that would violate the C/C++ mantra that those who do >>> not want a feature should not have to pay for it. >>> >>> Strict bounds checking - particularly checks per dimension as opposed to >>> a single check that the overall target lies within the array - would >>> break some existing code. >>> [For the same reasons that pointers may be one-of before or after the >>> array, and iterators may be considered to point "between" elements.] >> >> We're talking about the C++ STL "array" class, which is defined as having >> a certain size, with no guarantees about what lies outside the range of >> the actual data. > > Yes. But not every array in C++ uses the STL class, and I was reacting > to Simon's comment about the '[]' index operator. > > It would be hopelessly confusing if the index operator of the array > class was checked, but the general (C compatible) index operator was > not. If the general operator were checked, undoubtedly some code > would break, and even though STL arrays are heap allocated with some > overrun slop,
There are no such things as 'STL arrays', and the ones you probably talk about (containers?) are not guranteed to have overrun 'slop' (room before and after?). Wouter "Objects? No Thanks!" van Ooijen
Op 25-Mar-17 om 21:21 schreef Les Cargill:
> Wouter van Ooijen wrote: >> Op 24-Mar-17 om 00:17 schreef Tim Wescott: >>> I just put the following into yet another c/c++ file: >>> >>> #define DIM(x) (sizeof(x) / sizeof(*x)) >>> >>> It calculates the number of elements in the array x (assuming that >>> x is, indeed an array). >>> >>> Is there anything in the standard libraries that does this easy >>> and obvious thing? >> >> Just for my curiosity, why would you want to do that? You don't need >> it for iteration. >> >> Maybe to make a same-sized temporary array? But then it would make >> sense to name the array type, and use that type. But maybe for a >> same-sized array of a different element type. But I think I could >> make a template to do that. >> >> And if you do need it, if the array declaration is in scope, I >> assume that it was defined with some named literal dimension, so why >> not used that? >> >> Wouter "Objects? No Thanks!" van Ooijen >> > > A pattern I use frequently is to declare a table of const data without > giving it an extent, then have "const int lim = > sizeof(table)/sizeof(table[0]);" for a loop invariant for table > searches.
OK, fair enough. Do you know std::extent? constexpr int d2[] = { 1, 2, 3 }; std::cout << std::extent< decltype( d2 )>::value << "\n"; Or use std::array. It has a .size() the gives the number of elements. The only problem is that in the naive syntax you'd have to specify the number of elements, which defeats the whole purpose: std::array< int, 4 > data = { 1, 2, 3, 4 }; There is a function std::experimental::make_array which solves this, but it is apparently too new to be in my gcc. On http://stackoverflow.com/questions/26351587/how-to-create-stdarray-with-initialization-list-without-providing-size-directl I found this array_of function which seems to work fine: #include <array> template <typename V, typename... T> constexpr auto array_of(T&&... t) -> std::array < V, sizeof...(T) >{ return {{ std::forward<T>(t)... }}; } constexpr auto data = array_of< int >( 1, 2, 3, 5, 7 ); constexpr bool is_in_data( int x ){ for( size_t i = 0; i < data.size(); ++i ){ if( data[ i ] == x ) return true; } return false; } If you simple want to walk the array (instead of for instance a binary serach) it is of course easier to use a range-based for: constexpr bool is_in_data( int x ){ for( d : data ){ if( d == x ) return true; } return false; } And that could be rewritten using an STL agorithm, but personally I don't like the result. It will probably get better with ranges. Wouter "Objects? No Thanks!" van Ooijen
On 25/03/17 21:17, Les Cargill wrote:
> Hans-Bernhard Br&ouml;ker wrote: >> Am 25.03.2017 um 19:12 schrieb Les Cargill: >>> David Brown wrote: >> >>> I could not tell you which versions of which compilers support this, >>> but in some toolchains, it's possible to specify the size of an array >>> being passed - void p(char x[256])... . >> >> All C compilers are actually required to allow you to pass a size like >> that. It doesn't have any effect whatsoever, though. Any number you >> put between those [] is really just decoration. These 4 function >> declarations are totally equivalent: >> >> void p(char x[256]); >> void p(char x[7]); >> void p(char x[]); >> void p(char *x); >> >> > > I recall (vaguely) code where sizeof(x) would return 256, but it's a > hazy memory. I don't remember the toolchain; probably latter day MS > VS stuff.
That would be a broken compiler.
> > And even if it's just decoration, it preserves the size of the array out > of band. >
Specifying the size here is just a comment. And it is a dangerous comment, because it /looks/ like it might be something that the compiler will check, or that lets you use "sizeof" in the manner you describe - but it will not. In all the cases above, "x" is a pointer to char - /not/ an array.
David Brown wrote:
> On 25/03/17 21:17, Les Cargill wrote: >> Hans-Bernhard Br&ouml;ker wrote: >>> Am 25.03.2017 um 19:12 schrieb Les Cargill: >>>> David Brown wrote: >>> >>>> I could not tell you which versions of which compilers support >>>> this, but in some toolchains, it's possible to specify the size >>>> of an array being passed - void p(char x[256])... . >>> >>> All C compilers are actually required to allow you to pass a size >>> like that. It doesn't have any effect whatsoever, though. Any >>> number you put between those [] is really just decoration. These >>> 4 function declarations are totally equivalent: >>> >>> void p(char x[256]); void p(char x[7]); void p(char x[]); void >>> p(char *x); >>> >>> >> >> I recall (vaguely) code where sizeof(x) would return 256, but it's >> a hazy memory. I don't remember the toolchain; probably latter day >> MS VS stuff. > > That would be a broken compiler. >
It might have been a C++ toolchain. I don't recall. Those are out there for sure - although given all the furor over Blind Pointers Will Be The End of Western Civilization these days....
>> >> And even if it's just decoration, it preserves the size of the >> array out of band. >> > > Specifying the size here is just a comment.
It is and it isn't.
> And it is a dangerous > comment, because it /looks/ like it might be something that the > compiler will check, or that lets you use "sizeof" in the manner you > describe - but it will not. In all the cases above, "x" is a pointer > to char - /not/ an array. >
As a programmer, you have to check what things are. -- Les Cargill
Wouter van Ooijen <wouter@voti.nl> writes:
> There are no such things as 'STL arrays'
I believe we've been using the term to refer to this: http://en.cppreference.com/w/cpp/container/array
Op 26-Mar-17 om 20:08 schreef Paul Rubin:
> Wouter van Ooijen <wouter@voti.nl> writes: >> There are no such things as 'STL arrays' > > I believe we've been using the term to refer to this: > > http://en.cppreference.com/w/cpp/container/array
That type of array has nothing to do with heap storage, and it has zero overhead. (In contrast to for instance std::vector and other dynamically-sized array-like things, which do use the heap.) Wouter "Objects? No Thanks!" van Ooijen