EmbeddedRelated.com
Forums

Dimension of a matrix

Started by Tim Wescott March 23, 2017
On 30/03/17 04:55, Paul Rubin wrote:
> Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> writes: >> If I had my way, integers would be unsigned by default in all of today's >> programming languages and you would have to ask for a signed integer if >> you wanted one. > > What happens if you subtract 3 from 2? Are these unsigneds supposed to > represent natural numbers, so you throw an exception if you get a > negative result? Or are you saying all languages should use twos > complement wraparound arithmetic including the ones that have exact > integers now? >
Presumably he uses signed integers in situations where it makes sense to subtract 3 from 2, and in other situations he simply does not subtract 3 from 2. Making your "noOfOranges" variable signed does not let you subtract 3 oranges from 2 oranges.
On 3/29/2017 20:31, Les Cargill wrote:
> David Brown wrote: >> On 29/03/17 02:29, Les Cargill wrote: >>> David Brown wrote: >>>> On 28/03/17 08:42, Paul Rubin wrote: >>>>> Tim Wescott <tim@seemywebsite.com> writes: >>>>>> I don't write many bugs that have to do with overrunning >>>>>> array boundaries, particularly because I both inspect and >>>>>> test for it. >>>>> >>>>> It helps if you're writing embedded code, which tends to not >>>>> deal with too much variable sized data or have complicated >>>>> control flow. Otherwise how can you really tell? Inspection >>>>> stops helping much once the program is large enough. Do you do >>>>> any fuzz testing etc.? >>>>> >>>> >>>> I think the key point is program design, rather than testing. >>>> Testing can help show that you /have/ bugs, it doesn't show that >>>> you /don't/ have bugs. >>>> >>> >>> But design is about constraints, and testing can show that >>> constraints are met. That has a seriously Pareto ( 90/10 ) effect >>> on development outcomes. The other 10 percent takes the other 90 >>> percent of time allotted. >>> >>>> I don't have many bugs involving overrunning arrays either >>>> (despite being a mere human). I just make sure I know the size >>>> of my arrays when I use them. >>>> >>> >>> Me too. >>> >>> Apparently, that is too hard and we'll all suffer deadly >>> incursions. >>> >> >> There are some kinds of defects that can be avoided by good design. > > And that is really all this is. > >> Some kinds can be spotted by static error checking at compile time. >> And some kinds can be best spotted using tests. >> > > Static checking won't find much amongst people who have good > self-checking habits. I've seen two cases where ancient > code bases were cleaned up using static checkers, and it was mostly > noise. > > Where static analysis shines is "before every checkin." But it > all adds up. > >> Array overruns are best avoided by good programming practice - you >> know exactly what size your array is when you use it. > > Now how hard was that? > >> You don't >> make assumptions - make sure you /know/. And they are usually very >> hard to find by tests - the effect of an array overrun is typically >> "something odd is happening" because you have written to a different >> memory object unexpectedly. >> > > you effectively cannot reliably test for them. They must be > prevented by other practices. > >> You cannot sensibly use run-time checks of array sizes, except >> occasionally during development. You can only check the array bounds >> on access if you know the bounds - and if you know the bounds during >> the access, then the code that makes the accesses already knows these >> bounds and should not attempt such accesses. > > Yep.
I'd be concerned about code reuse. *I* will know about the array bounds and hopefully document them well and remember them when I pick up the code in six months. I'm not so sure that the next guy will do the right thing, particularly after I've left a project...
> >> At best, you might >> spot typographical errors - using "sizeOfInBuffer" when you meant >> "sizeOfOutBuffer". >> > > So I often start with "all buffers are the same size", > and then reduce them as needed, using a typedef enum to ... > enumerate all the possible sizes. > > In that case, you change one at a time, following it through > its entire lifetime. If you can't follow it through its entire lifetime, > then you have a much bigger problem. > > And to be totally honest, I'll at times "write an MMU" - have an array > of struct of the addresses and lengths of all the buffers, then add > extent checks that can be turned off. > > Most people who have buffer overrun problems have opaque void * style > buffer being flung around. Tsk. >
-- Best wishes, --Phil pomartel At Comcast(ignore_this) dot net
On 2017-03-30, David Brown <david.brown@hesbynett.no> wrote:
> On 30/03/17 04:55, Paul Rubin wrote: >> Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> writes: >>> If I had my way, integers would be unsigned by default in all of today's >>> programming languages and you would have to ask for a signed integer if >>> you wanted one. >> >> What happens if you subtract 3 from 2? Are these unsigneds supposed to >> represent natural numbers, so you throw an exception if you get a >> negative result? Or are you saying all languages should use twos >> complement wraparound arithmetic including the ones that have exact >> integers now? >>
If you think your variable might go negative, you use a signed integer otherwise you use an unsigned integer.
> > Presumably he uses signed integers in situations where it makes sense to > subtract 3 from 2, and in other situations he simply does not subtract 3 > from 2. Making your "noOfOranges" variable signed does not let you > subtract 3 oranges from 2 oranges. >
Exactly. You pick the data type which most closely models the problem you are trying to solve. Picking a signed integer when you know your data is always going to be positive is not a good match if unsigned integers are available in your chosen language. In my code (both work and hobbyist) I use unsigned values vastly more frequently than I do signed values and another reason is that signed integers have caused security issues in the past. Simon. -- Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP Microsoft: Bringing you 1980s technology to a 21st century world
Phil Martel wrote:
> On 3/29/2017 20:31, Les Cargill wrote: >> David Brown wrote: >>> On 29/03/17 02:29, Les Cargill wrote: >>>> David Brown wrote: >>>>> On 28/03/17 08:42, Paul Rubin wrote: >>>>>> Tim Wescott <tim@seemywebsite.com> writes: >>>>>>> I don't write many bugs that have to do with overrunning >>>>>>> array boundaries, particularly because I both inspect >>>>>>> and test for it. >>>>>> >>>>>> It helps if you're writing embedded code, which tends to >>>>>> not deal with too much variable sized data or have >>>>>> complicated control flow. Otherwise how can you really >>>>>> tell? Inspection stops helping much once the program is >>>>>> large enough. Do you do any fuzz testing etc.? >>>>>> >>>>> >>>>> I think the key point is program design, rather than testing. >>>>> Testing can help show that you /have/ bugs, it doesn't show >>>>> that you /don't/ have bugs. >>>>> >>>> >>>> But design is about constraints, and testing can show that >>>> constraints are met. That has a seriously Pareto ( 90/10 ) >>>> effect on development outcomes. The other 10 percent takes the >>>> other 90 percent of time allotted. >>>> >>>>> I don't have many bugs involving overrunning arrays either >>>>> (despite being a mere human). I just make sure I know the >>>>> size of my arrays when I use them. >>>>> >>>> >>>> Me too. >>>> >>>> Apparently, that is too hard and we'll all suffer deadly >>>> incursions. >>>> >>> >>> There are some kinds of defects that can be avoided by good >>> design. >> >> And that is really all this is. >> >>> Some kinds can be spotted by static error checking at compile >>> time. And some kinds can be best spotted using tests. >>> >> >> Static checking won't find much amongst people who have good >> self-checking habits. I've seen two cases where ancient code bases >> were cleaned up using static checkers, and it was mostly noise. >> >> Where static analysis shines is "before every checkin." But it all >> adds up. >> >>> Array overruns are best avoided by good programming practice - >>> you know exactly what size your array is when you use it. >> >> Now how hard was that? >> >>> You don't make assumptions - make sure you /know/. And they are >>> usually very hard to find by tests - the effect of an array >>> overrun is typically "something odd is happening" because you >>> have written to a different memory object unexpectedly. >>> >> >> you effectively cannot reliably test for them. They must be >> prevented by other practices. >> >>> You cannot sensibly use run-time checks of array sizes, except >>> occasionally during development. You can only check the array >>> bounds on access if you know the bounds - and if you know the >>> bounds during the access, then the code that makes the accesses >>> already knows these bounds and should not attempt such accesses. >> >> Yep. > I'd be concerned about code reuse.
I keep hoping to see a single example of effective code reuse before I stop working. A wise man once told me "reuse is at the team level" - you reuse teams familiar with the code, not just the code. No point in paying for the learning curve twice...
> *I* will know about the array bounds and hopefully document them well > and remember them when I pick up the code in six months.
Yes!
> I'm not so sure that the next guy will do the right thing, > particularly after I've left a project...
That's up to him/her. When I get a new code base, I tend to create a to-be-deleted branch and put in all sorts of instrumentation to establish what the rules of it are. IMO, the biggest sin programmers commit is trying to make ever second count as "productive time ", working towards an assigned goal. You gotta spend time with a code base to get to know it.
>> >>> At best, you might spot typographical errors - using >>> "sizeOfInBuffer" when you meant "sizeOfOutBuffer". >>> >> >> So I often start with "all buffers are the same size", and then >> reduce them as needed, using a typedef enum to ... enumerate all >> the possible sizes. >> >> In that case, you change one at a time, following it through its >> entire lifetime. If you can't follow it through its entire >> lifetime, then you have a much bigger problem. >> >> And to be totally honest, I'll at times "write an MMU" - have an >> array of struct of the addresses and lengths of all the buffers, >> then add extent checks that can be turned off. >> >> Most people who have buffer overrun problems have opaque void * >> style buffer being flung around. Tsk. >> > >
-- Les Cargill