Dimension of a matrix

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);

Reply to
Hans-Bernhard Bröker
Loading thread data ...

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
Reply to
Les Cargill

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
Reply to
Les Cargill

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

Reply to
George Neuner

Op 26-Mar-17 om 11:45 schreef George Neuner:

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

Reply to
Wouter van Ooijen

OK, fair enough.

Do you know std::extent?

constexpr int d2[] = { 1, 2, 3 }; std::cout ::value

Reply to
Wouter van Ooijen

That would be a broken compiler.

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.

Reply to
David Brown

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....

It is and it isn't.

As a programmer, you have to check what things are.

--
Les Cargill
Reply to
Les Cargill

I believe we've been using the term to refer to this:

formatting link

Reply to
Paul Rubin

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

Reply to
Wouter van Ooijen

Section 6.7.6.3 "Function declarators (including prototypes)" of the C standards has paragraph 7:

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. If the keyword static also appears within the [ and ] of the array type derivation, then for each call to the function, the value of the corresponding actual argument shall provide access to the first element of an array with at least as many elements as specified by the size expression.

Using an array as a parameter type has /exactly/ the same effect as using a pointer. Applying "sizeof" to it returns the size of a pointer.

C++ has the same thing (but without the option is using "static"). The wording in C++14 section 8.3.5 paragraph 5 is different but gives the same results.

As a programmer, you absolutely should /not/ have to check that the compiler follows the fundamental rules of the language you are using. A compiler - C or C++ - which gives the "sizeof" a C array parameter as the sizeof the array rather than the size of the pointer, is /broken/. This is not an option, or a feature, or something that some compilers do

- it is how C and C++ arrays work. And it is part of the reason for the introduction of std::array in C++.

Reply to
David Brown

Changing the behavior of the '[]' operator in native C++ code is a completely different class of change than changing the behavior of the '[]' operator in a library. The first requires a change to the underlying language definition, while the second is only a change to the library code.

--
Tim Wescott 
Control systems, embedded software and circuit design 
 Click to see the full signature
Reply to
Tim Wescott

Some people would disagree with that definition of "type-safe". :-)

And that's exactly why they would disagree. If the bounds are not enforced, then it's not type-safe IMHO.

Simon.

--
Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP 
Microsoft: Bringing you 1980s technology to a 21st century world
Reply to
Simon Clubley

In an ideal world, I wouldn't mind seeing the first one become reality either. Yes, it would break some bad code, but that existing code could easily be a CVE just waiting to happen.

Simon.

PS: And yes, I know about the C++ speed over safety design goals... :-)

--
Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP 
Microsoft: Bringing you 1980s technology to a 21st century world
Reply to
Simon Clubley

I think that would have so many ugly tentacles extending into all parts of how C natively handles arrays that it would be a nightmare all around.

Much better to just have people remember that '[]' is inherently unsafe, and Pay Attention, imho.

--
Tim Wescott 
Wescott Design Services 
 Click to see the full signature
Reply to
Tim Wescott

Type safety is primarily a compile-time feature. The aim of type safety is to stop you trying to use the wrong "type" of "thing" (objects, classes, types, whatever) in the wrong place. And by restricting the operations you can do on your "things", you spot more mistakes at compile-time. A vital point is that type safety checks are free with respect to run-time costs. And your aim is to stop certain classes of error being /possible/.

Checking the bounds of array accesses is primarily a run-time feature. There are run-time safety checks you can make - they are not type safety checks. They involve some run-time overhead, and you need run-time methods of dealing with detected errors - your aim is to detect certain classes of error when they happen, and stop them leading to worse problems.

Sometimes there is a middle ground. The compiler may be able to check, at compile time, whether an array access is always safe, possibly safe, or always bad. It is certainly a good thing if the compiler can warn you on third case, and omit any run-time checks in the first case.

You can argue that a std::array type is a type with a fixed known size, and therefore should not allow any access beyond its bounds. But actually it is defined as a type that wraps a C array with no run-time overheads for normal use, without run-time checking of bounds. It gives you methods for accessing the data, but there is a pre-condition on the [] operator that you are within the bounds of the array. This is a perfectly good way to define a type and its operations - type-safety does /not/ require run-time checking that pre-conditions to methods are met. That is the responsibility of the code using the type.

Of course one could make a type for which bounds checking was part of the [] operator method specification. But even then, the check is not part of the type safety system because the index is not part of a type, and the check is not at compile-time. If you want that kind of type safety, use a std::tuple and get functions for access - /those/ accesses are type checked.

Reply to
David Brown

Sorry, but you can't just redefine "type safety" to mean "static type safety" and exclude "dynamic type safety".

I get it, static >> dynamic, but they're both about type safety.

Clifford Heath.

Reply to
Clifford Heath

Fair enough, I suppose. C++ supports dynamic type safety too, such as the dynamic_cast operator. But static type safety is the main mechanism for type safety in C++.

std::array is defined to be a type with greater static type safety compared to standard C/C++ arrays - it knows its size, does not decay to a pointer, etc. It is not defined to have run-time bounds checking by default - but you have the option if you want (with the "at" method).

Type safety - dynamic or static - does not mean preventing any possible errors. It merely means making it hard to accidentally make errors from mixing up types - and it is a balance between safety, convenience (in writing the code) and efficiency (code size and speed at run-time). It is not an absolute term (at least, not in real-world programs in real-world programming languages). It would be fair to say that an array container that always checked its bounds is /safer/ than std::array, and is more "type safe". But it could never be completely type safe - not in C++, where you have reinterpret_cast, unions, void*, memcpy, and all sorts of other ways to cheat on type safety.

Reply to
David Brown

And my, that theory has worked out well in practice, hasn't it. :(

Reply to
Tom Gardner

I don't write many bugs that have to do with overrunning array boundaries, particularly because I both inspect and test for it. I certainly do plenty of other dumbass things, because I'm not human.

There's always Ada if that sort of thing is a concern -- and you don't have to completely change the semantics of arrays to make it work, because Ada arrays have that set of semantics built in.

--
Tim Wescott 
Control systems, embedded software and circuit design 
 Click to see the full signature
Reply to
Tim Wescott

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.