Re: C is not a low level language

> And if more programs were written in it we would have programs of one > tenth the size runninmg ten times faster and a huge number of crap > programmers would be flipping burgers.

KUDOS!!!!!!!!!!!!! I say that in StackOverflow and had my account banned. ;-)

Reply to
Ozz Nixon
Loading thread data ...

I missed the OP, but the thread title seems to me to be in error, because AIUI the whole purpose of the cast facility is to be able to cast a number as an integer pointer for accessing memory=mapped I/O.

Can't get much lower than that!

Reply to
Gareth's was W7 now W10 Downstairs Computer

That is one use for it, far from the only one. It is also very useful in many situations where an OO approach might seem more natural but the efficiency of directly controlling the memory behaviour matters.

--
Steve O'Hara-Smith                          |   Directable Mirror Arrays 
C:\>WIN                                     | A better way to focus the sun 
 Click to see the full signature
Reply to
Ahem A Rivet's Shot

That was the beauty of C. Years ago I was handed a ghastly hack of TurboPascal that needed to read a ram disk clock, and decide whetheer it was a FAT, File entry, or a data block. Based on the first few bytes it might be almost anything.

It proved quicker to write it in C where the data block could be read as an array of words, then depending on the value of some works, cast into an array of something else or a struccture...

...I spent an entire Sunday rewriting the whole program in C in a hotel room in Orleans...

I love the fact that C will gently ask whether you really meant to treat an integer as a pointer to a string, and assume that oince you explicitly cast it so, you are clever enough to mean it.

Only once has C let me down. In Assembler it is trivial to set up a call table - an arraye of address of subroutines that are called depending on an indexz value in te accumultaor. You take the base address of te aqrray into one regsiter, add the left shifted (on an 8 bit mnicro) accumulator to it and call te address ponted to by that register.

And array of pointers to functions was beyond my ability to specify, and the crude 6809 compiler to understand anyway.

So I wrote it as an 'if then... else if..' chain...

--
Ideas are more powerful than guns. We would not let our enemies have  
guns, why should we let them have ideas? 
 Click to see the full signature
Reply to
The Natural Philosopher

If you want OO *structure* you can use it in pure C by using siource fuiles littered with STATICs and conatining their own data and their won menss of modifying te dayta by function calls.

Operator overloeading? The whole reason I write in C is precisely becaiuse I do not want inadvertent passing of a numercal string to a function expecting an integer to second guess me. It's a MISTAKE, not a feature.

OO langeus are like fixed speed linmits. Ok for numpties but a pain in te ass for peoole who know how to drive in all conditions.

And then we hasve 'code generators' because no one can program in them anyway...

--
"And if the blind lead the blind, both shall fall into the ditch". 

Gospel of St. Mathew 15:14
Reply to
The Natural Philosopher

More a demonstration of a lack of experience with turbo pascal than anything else. It will go low down and dirty if you want and give you raw memory access, untyped pointers etc.

You mean like having an array of function pointers in C, and calling the one at a certain index?

You can get lame compilers for pretty much any language IME!

No "switch" statement?

--
Cheers, 

John. 
 Click to see the full signature
Reply to
John Rumm

Never found out how to in the four hours I spent reading the manual

There was, but on a 6809 the code was simply horrible.

I only had IIRC three possibles. so if then else if then else

was pretty compact.

>
--
To ban Christmas, simply give turkeys the vote.
Reply to
The Natural Philosopher

(too many newsgroups, had to snip a few)

Richard,

:-) And thats exactly the kind of thing you should try to avoid.

In this simple example it will work, but you're /still/ trying to write a full buffers worth - when you should leave that last character untouched, just in case.

Ofcourse, I would rather check the length of the to-be-copied string and throw an error when it doesn't fit, but maybe thats just me ... (Just imagine you're copying some kind of commandline string, with a few argument switches at the end).

Regards, Rudy Wieser

Reply to
R.Wieser

That is an option if you know roughly what SHOULD be there.

--
"The most difficult subjects can be explained to the most slow witted  
man if he has not formed any idea of them already; but the simplest  
 Click to see the full signature
Reply to
The Natural Philosopher

(Sorry, didn't notice. But you left comp.programming in, so we're good.)

That last character is the null terminator. Given the choice, that's how I like my strings to end. :-)

Okay, so that's so obvious a retort that I have to deduce you meant something else, but I don't know what. Care to explain for the benefit of my befuddled grey cells?

Reporting an error is certainly preferable to undefined behaviour, but I would prefer to grab the data - all of it - if that's possible and reasonable.

(There may be times when it's *not* reasonable to try to grab all the data - for example, if someone is deliberately throwing complete-Shakespeare-in-one-line at you over and over again in an attempt to make you consume the whole of memory. So of course you have to do your threat assessment: is the program going to be used in a context where this sort of thing is likely? If so, you need some rules for how much data is to be considered acceptable.)

--
Richard Heathfield 
Email: rjh at cpax dot org dot uk 
 Click to see the full signature
Reply to
Richard Heathfield

Richard,

You responded to a post in which was explained that "strncpy" could be dangerous because you could fill the buffer out with a too-long string, leaving it without a terminator. The defensive method would be to stop copying before you overwrite the last byte in the target buffer - thereby making sure that whatever may happen, the buffer will hold a zero-terminated string.

I went along with you upto-and-including the "- all of it -". The latter part ? Not so much. Not even humans are really capable of acting (correctly!) on partial messages, let alone un-imaginative programs. And boy, can they do a lot of damage ...

Regards, Rudy Wieser

Reply to
R.Wieser

TNP,

You got that backwards I'm afraid: the usage of "strncpy" in a "disregard whatever you can't copy" way is only a good(ish) idea when you /know/ that what you dropped is of no consequence.

In all other circumstances letting a program (or human!) act on partial data will be a hommage to the old "garbage in, garbage out" saying. :-)

Regards, Rudy Wieser

Reply to
R.Wieser

With you so far...

But my code protected against that possibility by obtaining the length of the source string including terminator: len = strlen(src) + 1; and then allocating exactly that amount of memory via malloc, and then using memcpy to copy exactly that many bytes. The only way this could break would be if the source string grew between two consecutive lines of code that did not grow that string. This *could* happen in a multi-threaded context, of course, but in a multi-threaded context one would take additional precautions to ensure that only one thread had access to the string at the point of duplication.

OR... I'm missing something! :-)

Well, if it's impossible it's impossible and that's all there is to it. And I gave an example of a scenario in which an unreasonable amount of data could be deliberately thrown at the program with the express intent of consuming all available memory. If these circumstances are at all likely, it seems to me that it is better to protect against them than to succumb blindly to them.

--
Richard Heathfield 
Email: rjh at cpax dot org dot uk 
 Click to see the full signature
Reply to
Richard Heathfield

Richard,

Thats why I said "In this simple example it will work".

In your example ? Yes (and the same as I was thinking).

Now imagine that you're programming and you /could/ be working on a single-thread string, but as easily on a multi-thread one. Wouldn't it be easier to use a method which will work in either circumstance ?

True. But that only goes as far as the programmer can imagine such attacks. "strncpy" is ment as a "last ditch" effort to safeguard against the /unforseen/ circumstances which could lead to memory/stack being clobbered. My suggestion to provide it an argument that is one less than what the buffer can actually hold is just an extension on that.

Personally I would not mind at all when it would throw or return an error when the target buffer was found to be too small for the source string. It should never happen, and for that reason should not be silently ignored either. But thats just my take on it, YMMV.

Regards, Rudy Wieser

Reply to
R.Wieser

I will grant that some programmers might be in that position, but I'm not one of them.

It has rightly been said that threading is for people who don't understand state machines, and state machines are for people who don't understand threading. I am in the latter camp!

In the more general case, however, your point is taken.

--
Richard Heathfield 
Email: rjh at cpax dot org dot uk 
 Click to see the full signature
Reply to
Richard Heathfield

"Just in case" what, exactly? Are you trying to guard against an off-by-one error but not worry about an off-by-two error?

--
Keith Thompson (The_Other_Keith) kst-u@mib.org   
Will write code for food. 
 Click to see the full signature
Reply to
Keith Thompson

Assuming you bzeroed the target block before copying first. strncpy does npot zero terminate te target block

Well sometimes one can say 'sorry buffer overflowed: can you resend that last bit"

Case where its nopt reasonable to garb all et data? well mail programs. I blacklist anything endi in .tv, .info, .biz and dozens of other top level domains that are entirely owned by spam marketing companies.

I only grab enough data to establish that before sending them packing

--
You can get much farther with a kind word and a gun than you can with a  
kind word alone. 
 Click to see the full signature
Reply to
The Natural Philosopher

Hey, I understand both!

And have written code to implement both!

Sometimes in the same program! That was the program that also uses longjmp()

30 subroutrines deep you are reading characters from a telex line, and the line drops...exit up through 30 subs? nah. set an error code LINE_DROP and longjmp back to an exit point, look at the error code and clean up the hardware and print what of the telex you did get...

I remember sitting with a telex directory deliberatrely tring to contact companies in equatorial africa to send them test telexes on the basis that they were usually only capable of sustaining a connection till the mext lightning strike.

No idea who they were.

--
Socialism is the philosophy of failure, the creed of ignorance and the  
gospel of envy. 
 Click to see the full signature
Reply to
The Natural Philosopher

"R.Wieser" writes: [...]

No, strncpy is designed to work with a specific (and, in recent history, rare) data structure, namely a fixed-length character array containing some bytes of meaningful data padded to the end by zero or more null bytes. (I believe it was used to store file names in Unix directory entries.)

(followups to comp.lang.c only)

--
Keith Thompson (The_Other_Keith) kst-u@mib.org   
Will write code for food. 
 Click to see the full signature
Reply to
Keith Thompson

Yeah the manuals and built in help improved massively with later versions, but were a bit sparse for the early versions.

There was s significant improvement with V4 IIRC (although the footprint of the development system got *much* larger as well - V3 always amazed me in that it included editor, compiler, linker, run time system etc all in a single 50K executable!).

The neatest way to do that in TP was usually to create a "Packed"[1] Variant Record data structure (like a union in C), with whatever fields you want, and then have variants that treat the data in other ways - something like a straight array of bytes. E.g:

var buffer [0..BuffSize] of byte ;

(or if you want it true C style just make the array a single byte long and then index off the end of it - the compiler did not range check unless you explicitly told it to)

[1] Using a packed record stopped the compiler padding the structure for efficiency - say moving byte wide fields onto word boundaries)

Then when you create in instance of that record, you could map it to an absolute memory location using the "absolute" keyword and specifying the address.

There was also a predefined array called mem that simply mapped to memory.

Yup gets the job done, and in code terms is not usually going to be any worse that a switch.

--
Cheers, 

John. 
 Click to see the full signature
Reply to
John Rumm

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.