Author Topic: the c-semantics project is aimed against - C undefined behavior -  (Read 19402 times)

0 Members and 1 Guest are viewing this topic.

Offline tjaeger

  • Regular Contributor
  • *
  • Posts: 101
Re: the c-semantics project is aimed against - C undefined behavior -
« Reply #25 on: March 27, 2014, 06:27:44 pm »
Has anyone tried kcc?  I have a seasick-like feeling when I hear about YAC (yet another compiler). Could they not fork an existing compiler in hopes of a future merge? Clang? Gcc? Have I missed the whole point?
No, they couldn't given the goals of their project.  This is not a compiler that spits out object code.  Its output is interpreted by the rewriting logic engine Maude.  The point of this is not to actually run the code in a production environment, but to perform static and run-time analysis (for example to catch undefined behavior).
 

Offline GiskardReventlov

  • Frequent Contributor
  • **
  • Posts: 598
  • Country: 00
  • How many pseudonyms do you have?
Re: the c-semantics project is aimed against - C undefined behavior -
« Reply #26 on: March 27, 2014, 06:35:24 pm »
@tjaeger, ok that's good, then I can try it out, I've been building kicad and haven't looked at the code (apparently it's not recommended to look at) but will try kcc on it. Emphasis on "try".
 

Offline Jarrod Roberson

  • Regular Contributor
  • *
  • Posts: 71
Re: the c-semantics project is aimed against - C undefined behavior -
« Reply #27 on: March 27, 2014, 06:41:54 pm »
There are lies, damn lies and the TIOBE index.

Do a simple google search and you will find out why this TIOBE index is worst than useless, it doesn't use any scientific principals to gather OR interpret the data.

Any professor who presents TIOBE index as anything than something that should be ignored isn't qualified to be teaching anyone anything!
 

Offline tjaeger

  • Regular Contributor
  • *
  • Posts: 101
Re: the c-semantics project is aimed against - C undefined behavior -
« Reply #28 on: March 27, 2014, 06:49:49 pm »
@tjaeger, ok that's good, then I can try it out, I've been building kicad and haven't looked at the code (apparently it's not recommended to look at) but will try kcc on it. Emphasis on "try".

kicad is written in C++, so this won't work.  Even if it were written in C, I doubt kcc could handle a project of this scale.
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: the c-semantics project is aimed against - C undefined behavior -
« Reply #29 on: March 27, 2014, 06:54:51 pm »
Quote
but I found this plot interesting when presented in the embedded C online course I am taking

Looks like some embedded engineers are trying to make a living writing code for smart phones and apps.

Good for them.
================================
https://dannyelectronics.wordpress.com/
 

Online IanB

  • Super Contributor
  • ***
  • Posts: 11887
  • Country: us
Re: the c-semantics project is aimed against - C undefined behavior -
« Reply #30 on: March 27, 2014, 07:57:55 pm »
I should have read the paper more in detail, tjaeger seems to be right, I just scanned the doc until section 3.2 and it seemed to imply that
Code: [Select]
unsigned int a = 1000, b = 1000;
long int c = a * b;

should give you c = 1000000 but it really states that it's defined to be the value that fits in an unsigned int since it's not promoted to the type of the receiving variable. i.e. 0x000F4240 truncated to 16 bits 0x4240 so the result will be 16960.

So what they really are doing is to get the code to comply with the standard, not redefine the standard and they are focusing on C1X since it will overcome C99 as far as they are concerned.

But the standard defines exactly what should happen in the code sample you posted. In that sample "a * b" is an expression and the evaluation of that expression depends on the variable types of a and b according to very well defined promotion rules. Once the expression is evaluated and a result generated, then something may be done with that result, for example assign it to another variable. The key thing is that what you are going to do with the result later on does not influence how the result is computed to begin with. This is a principle found not only in C.

In regard to your closing paragraph, this behavior is nothing to do with noncompliance with standards. The standard is unambiguous about what should happen there.
 

Offline tjaeger

  • Regular Contributor
  • *
  • Posts: 101
Re: the c-semantics project is aimed against - C undefined behavior -
« Reply #31 on: March 27, 2014, 08:09:04 pm »
I should have read the paper more in detail, tjaeger seems to be right, I just scanned the doc until section 3.2 and it seemed to imply that
Code: [Select]
unsigned int a = 1000, b = 1000;
long int c = a * b;

should give you c = 1000000 but it really states that it's defined to be the value that fits in an unsigned int since it's not promoted to the type of the receiving variable. i.e. 0x000F4240 truncated to 16 bits 0x4240 so the result will be 16960.

So what they really are doing is to get the code to comply with the standard, not redefine the standard and they are focusing on C1X since it will overcome C99 as far as they are concerned.

But the standard defines exactly what should happen in the code sample you posted. In that sample "a * b" is an expression and the evaluation of that expression depends on the variable types of a and b according to very well defined promotion rules. Once the expression is evaluated and a result generated, then something may be done with that result, for example assign it to another variable. The key thing is that what you are going to do with the result later on does not influence how the result is computed to begin with. This is a principle found not only in C.
No. In this example, sizeof(int) was supposed to be 2 and the behavior of the code fragment is undefined.
 

Offline grumpydoc

  • Super Contributor
  • ***
  • Posts: 2905
  • Country: gb
Re: the c-semantics project is aimed against - C undefined behavior -
« Reply #32 on: March 27, 2014, 08:42:47 pm »
Quote from: IanB
But the standard defines exactly what should happen in the code sample you posted.

Quote from: tjaeger
No. In this example, sizeof(int) was supposed to be 2 and the behavior of the code fragment is undefined.

In some ways both of the above statements are actually true.

The promotion rules for the expression evaluation are well defined.

The value of what gets assigned to c is undefined purely because C does not define what happens when an integer expression overflows (normally it's just whatever the underlying CPU does).

 

Offline jancumps

  • Supporter
  • ****
  • Posts: 1272
  • Country: be
  • New Low
Re: the c-semantics project is aimed against - C undefined behavior -
« Reply #33 on: March 27, 2014, 08:59:27 pm »
...

Not that this has stopped me designing and writing some large projects in C++ :)
Same here. I've earned a decent paycheck for years writing large projects (erp and airoplane handling related) in C++ in the 90s.
 

Offline tjaeger

  • Regular Contributor
  • *
  • Posts: 101
Re: the c-semantics project is aimed against - C undefined behavior -
« Reply #34 on: March 27, 2014, 09:00:07 pm »
The value of what gets assigned to c is undefined purely because C does not define what happens when an integer expression overflows (normally it's just whatever the underlying CPU does).
No, the behavior of the program is undefined.  There are absolutely no guarantees of this sort.  For example, if the next few lines are
Code: [Select]
if (c == 0)
  a();
if (c != 0)
  b();
then the compiler is under no obligation to call either a() or b().
 

Offline granz

  • Regular Contributor
  • *
  • Posts: 136
  • Country: us
  • 6.62606957
Re: the c-semantics project is aimed against - C undefined behavior -
« Reply #35 on: March 27, 2014, 09:10:32 pm »
It's always seemed strange to me that people see C as a language particularly well-suited to microcontroller development, rather than a flawed language that we ended up with for historical reasons that's just barely good enough for programmers (who are creatures of habit) to not seek alternatives.  Even some things that are trivial to code in assembler. like adding up two signed integers and checking for overflow, are next to impossible to do in C.

Microcontrollers vary widely.  How would you create a universally consistent language for microcontrollers anyhow?  C has several undefined behaviors to keep it from being tied to any particular architecture.  C allows inline asm to check platform dependent flags etc.
That's not really true.  C has implementation-defined behavior to cope with different architectures.  So for example when you cast a signed int to an unsigned int, you can get two's complement, one's complement or sign-absolute value depending on architecture. Undefined behavior is much more insidious and its rationale is to enable certain optimizations (if not outright mean-spiritedness).  So if you're implementing a binary heap and you realize that it costs less cycles to move between parent and children in 1-indexed arrays rather than 0-indexed arrays and you do things like
Code: [Select]
uint32_t a[16] = {0, };
uint32_t *heap = a-1;
you're might be in for a surprise depending on how aggressively your compiler optimizes.

Quote
Many people have tried for a long time to come up with alternatives.  Interpreted languages such as Java or C# essentially solve all of the undefined behavior issues, but the price is paid for in performance.  On a PC when you are writing application software it's worth it, but on a Microcontroller you aren't writing portable code anyhow--you are very tied to the hardware anyway.
It's the other way around.  Undefined behavior is a problem when you want to be tied to the hardware as closely as possible because the compiler is under no obligation to translate your code to what you would think it should correspond to.

I not quite sure *how* you a disagreeing with me, but it seems you are.  I never said undefined behavior wasn't a problem, and you may have noticed that my first post mentioned that the c-semantics project would have uses.  I just doubt its usefulness for many firmware development projects, since often bugs stem from incorrectly interacting with peripherals etc.  This is how I interpreted the original question.

Undefined behavior is intended to aid in optimizations for sure, but I don't see how that negates it being related to platform differences.

For example, from the LLVM blog:

http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html

Quote
Shifting a uint32_t by 32 or more bits is undefined. My guess is that this originated because the underlying shift operations on various CPUs do different things with this: for example, X86 truncates 32-bit shift amount to 5 bits (so a shift by 32-bits is the same as a shift by 0-bits), but PowerPC truncates 32-bit shift amounts to 6 bits (so a shift by 32 produces zero). Because of these hardware differences, the behavior is completely undefined by C (thus shifting by 32-bits on PowerPC could format your hard drive, it is *not* guaranteed to produce zero). The cost of eliminating this undefined behavior is that the compiler would have to emit an extra operation (like an 'and') for variable shifts, which would make them twice as expensive on common CPUs.

My point was essentially, how would you fix those undefined behaviors in a consistent manner across architectures, without affecting performance on some platforms?  Sure you can identify them in generic C code, but then you just avoid those particular situations.  If you really need the performance you write that part in asm where the behavior is defined by the particular architecture.


 

Online IanB

  • Super Contributor
  • ***
  • Posts: 11887
  • Country: us
Re: the c-semantics project is aimed against - C undefined behavior -
« Reply #36 on: March 27, 2014, 09:43:41 pm »
No. In this example, sizeof(int) was supposed to be 2 and the behavior of the code fragment is undefined.

If the rules say the behavior is undefined in that situation, you have no business writing that code. More fool you.
« Last Edit: March 27, 2014, 09:45:19 pm by IanB »
 

Offline tjaeger

  • Regular Contributor
  • *
  • Posts: 101
Re: the c-semantics project is aimed against - C undefined behavior -
« Reply #37 on: March 27, 2014, 09:59:58 pm »
It's the other way around.  Undefined behavior is a problem when you want to be tied to the hardware as closely as possible because the compiler is under no obligation to translate your code to what you would think it should correspond to.

I not quite sure *how* you a disagreeing with me, but it seems you are.  I never said undefined behavior wasn't a problem, and you may have noticed that my first post mentioned that the c-semantics project would have uses.  I just doubt its usefulness for many firmware development projects, since often bugs stem from incorrectly interacting with peripherals etc.  This is how I interpreted the original question.

Undefined behavior is intended to aid in optimizations for sure, but I don't see how that negates it being related to platform differences.
Undefined behavior is generally not a good way to deal with hardware differences.  The point of undefined behavior is to allow the compiler to make assumptions about the code that it can't prove statically.
Quote
For example, from the LLVM blog:

http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html

Quote
Shifting a uint32_t by 32 or more bits is undefined. My guess is that this originated because the underlying shift operations on various CPUs do different things with this: for example, X86 truncates 32-bit shift amount to 5 bits (so a shift by 32-bits is the same as a shift by 0-bits), but PowerPC truncates 32-bit shift amounts to 6 bits (so a shift by 32 produces zero). Because of these hardware differences, the behavior is completely undefined by C (thus shifting by 32-bits on PowerPC could format your hard drive, it is *not* guaranteed to produce zero). The cost of eliminating this undefined behavior is that the compiler would have to emit an extra operation (like an 'and') for variable shifts, which would make them twice as expensive on common CPUs.
While the post that you're quoting is generally well-written, this paragraph just doesn't make any sense.  The standard committee had a few reasonable choices as to how to deal with shift-past-bitwidth:
  • Define shift-past-bitwidth to be 0: This would incur a performance penalty on some architectures, but programmers could easily get around that if compilers would emit efficient code for "assert(i >=0 && i < 32); foo = bar >> i;"
  • Make this behavior implementation-defined: In that case, you could still rely on a certain behavior on a particular architecture, but your code would be non-portable.
  • Leave the value of the operation unspecified: Now it's perfectly legal to execute a shift-past bitwidth operation, but you don't have any guarantees about what the result is.
Making the behavior of shift-past-bitwidth undefined is not reasonable unless there are architectures that handle it like some do division by zero -- by emitting a trap.

Quote
My point was essentially, how would you fix those undefined behaviors in a consistent manner across architectures, without affecting performance on some platforms?  Sure you can identify them in generic C code, but then you just avoid those particular situations.  If you really need the performance you write that part in asm where the behavior is defined by the particular architecture.
Having the behavior be implementation-defined rather than undefined would give you most of the benefits.
 

Offline tjaeger

  • Regular Contributor
  • *
  • Posts: 101
Re: the c-semantics project is aimed against - C undefined behavior -
« Reply #38 on: March 27, 2014, 10:02:07 pm »
No. In this example, sizeof(int) was supposed to be 2 and the behavior of the code fragment is undefined.

If the rules say the behavior is undefined in that situation, you have no business writing that code. More fool you.
What??? You were the one that wrote
Quote
But the standard defines exactly what should happen in the code sample you posted.
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: the c-semantics project is aimed against - C undefined behavior -
« Reply #39 on: March 27, 2014, 10:22:46 pm »
I have to agree that C isn't suited to some targets, as ANSI C makes quite a few assumptions about the hardware model, including:

- That you have a deep stack,
- That you have STDIN, STDOUT and STDERR
- THat you have something to return to (e.g. an OS or DOS prompt)
- That your program and data memory space is the same address space

This is why there is no decent 'C" for 16F84 series PICs (which are great microcontrollers BTW).

I guess that AVR were careful when designing the ATmega to ensure that 'C' almost fits their hardware, except maybe for all that silly PROGMEM stuff...
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 

Offline grumpydoc

  • Super Contributor
  • ***
  • Posts: 2905
  • Country: gb
Re: the c-semantics project is aimed against - C undefined behavior -
« Reply #40 on: March 27, 2014, 10:29:54 pm »
The value of what gets assigned to c is undefined purely because C does not define what happens when an integer expression overflows (normally it's just whatever the underlying CPU does).
No, the behavior of the program is undefined.  There are absolutely no guarantees of this sort.  For example, if the next few lines are
Code: [Select]
if (c == 0)
  a();
if (c != 0)
  b();
then the compiler is under no obligation to call either a() or b().
OK, technically you are completely correct - in fact it would be standards conforming for the compiler to emit code to detect the overflow, print "I am a frog" and then explode although that's not an especially helpful way to write a compiler. Mind you ISTR that gcc did detect some #pragma's and, after trying to start hack, rogue or the towers of Hanoi simulation in emacs print the message "You are in a maze of twisty compiler features, all different"

It's not even hard to envisage a scenario where neither of the if's in your example would execute - because the overflow caused a hardware exception and the code never got to that point.

But, assuming that's not the case and that the compiler writers were not especially inventive in their vindictiveness the most likely scenario is that the multiply will silently fail and some value will end up in c - not necessarily 16960 either.

Arguably this is actually less useful than printing "I am a frog" and then exploding  >:D
« Last Edit: March 27, 2014, 11:29:03 pm by grumpydoc »
 

Offline grumpydoc

  • Super Contributor
  • ***
  • Posts: 2905
  • Country: gb
Re: the c-semantics project is aimed against - C undefined behavior -
« Reply #41 on: March 27, 2014, 10:48:15 pm »
I have to agree that C isn't suited to some targets, as ANSI C makes quite a few assumptions about the hardware model, including:

- That you have a deep stack,
- That you have STDIN, STDOUT and STDERR
- THat you have something to return to (e.g. an OS or DOS prompt)
- That your program and data memory space is the same address space

This is why there is no decent 'C" for 16F84 series PICs (which are great microcontrollers BTW).

I guess that AVR were careful when designing the ATmega to ensure that 'C' almost fits their hardware, except maybe for all that silly PROGMEM stuff...
I'm not clear that ANSI C does make those assumptions, at least not from the point of view of the language itself. The standard C library might be a different issue.

You don't need a hardware stack and as long as you have some sort of "jump and store the current program counter" and the ability to load the program counter with a computed value (even if via a trampoline) you can manage with a stack implemented in software.

STDIN, STDOUT and STDERR are more library than language concepts. You don't need to '#include <stdio.h> to write C code.

There is also no need for "somewhere to return to" since a C program needn't terminate. Some sort of environment to invoke your program is needed but that could itself be written in C, perhaps with a little bit of assembly language thrown in (hint, quite a few OSes are substantially written in C).

I'm pretty certain that C itself does not require a single address space - you do need to be able to manipulate code addresses to the extent of being able to store them and jump (or rather call) to a computed address (otherwise function pointers can't be implemented) but the language doesn't say you can read anything from the memory referenced by a function pointer.

Edit
Quote
This is why there is no decent 'C" for 16F84 series PICs (which are great microcontrollers BTW).

To be fair, if I'm reading the datasheet correctly (I've never used one) the 16F84 has 1024 words of program memory, 68 bytes of RAM and 64 bytes of EEPROM.

It wouldn't be impossible to target that with a C compiler but I'd think it was a bit of a challenge for any high level language.
« Last Edit: March 27, 2014, 10:54:42 pm by grumpydoc »
 

Online IanB

  • Super Contributor
  • ***
  • Posts: 11887
  • Country: us
Re: the c-semantics project is aimed against - C undefined behavior -
« Reply #42 on: March 27, 2014, 11:08:35 pm »
No. In this example, sizeof(int) was supposed to be 2 and the behavior of the code fragment is undefined.

If the rules say the behavior is undefined in that situation, you have no business writing that code. More fool you.
What??? You were the one that wrote
Quote
But the standard defines exactly what should happen in the code sample you posted.

But I also read and take account of what others write and include it in my considerations.

The standard says that a particular implementation defines the size of an int on that platform (within certain constraints). The standard defines promotion rules for expressions involving mixed types. The outcome of these rules is that the result of a multiplication between two 16 bit signed integers will be a 16 bit signed integer.

But from what I read subsequently, the standard does not define what the result should be if that multiplication overflows (something I did not consider originally).

That being the case, you should be careful that your multiplications do not overflow if you care about having a portable outcome. One possibility in the case given (where perhaps inputs are in the range 0 .. 1000) is to use "long int" instead of "int", since a long int is guaranteed to have at least 32 bits.
 

Offline miguelvp

  • Super Contributor
  • ***
  • Posts: 5550
  • Country: us
Re: the c-semantics project is aimed against - C undefined behavior -
« Reply #43 on: March 28, 2014, 12:38:12 am »
I should have read the paper more in detail, tjaeger seems to be right, I just scanned the doc until section 3.2 and it seemed to imply that
Code: [Select]
unsigned int a = 1000, b = 1000;
long int c = a * b;

should give you c = 1000000 but it really states that it's defined to be the value that fits in an unsigned int since it's not promoted to the type of the receiving variable. i.e. 0x000F4240 truncated to 16 bits 0x4240 so the result will be 16960.

So what they really are doing is to get the code to comply with the standard, not redefine the standard and they are focusing on C1X since it will overcome C99 as far as they are concerned.

But the standard defines exactly what should happen in the code sample you posted. In that sample "a * b" is an expression and the evaluation of that expression depends on the variable types of a and b according to very well defined promotion rules. Once the expression is evaluated and a result generated, then something may be done with that result, for example assign it to another variable. The key thing is that what you are going to do with the result later on does not influence how the result is computed to begin with. This is a principle found not only in C.

In regard to your closing paragraph, this behavior is nothing to do with noncompliance with standards. The standard is unambiguous about what should happen there.

Yes, that's what I was trying to say, that when it's defined they leave it alone. I did read the paper further and changed my mind on kcc being a good idea and here is why:

When it's undefined they just stop execution, for example if those variables where signed then the result will be undefined by the standard so it will stop execution in that case and give a run time error. That itself implies programming overhead, I don't want that.

The worse of it is when I found out that they are actually checking for things that are not even part of the C language, for example checking if strcpy is copying out of bounds. I don't consider strcpy part of C so the compiler shouldn't be even care about functions or their interpretation on how a function should behave.

So I'm changing sides again and I'm back on the side of this compiler not worth a thing.

Edit: Clarification, not worth a thing for embedded programming. (also I said numbers when I meant variables so I changed that too).

And btw I love C++ but I love C too and Assembly as well, an even Python. But they are tools that you use depending on the job. Sure I can use a butter knife to unscrew something, but I rather use the proper tool for the job.

C++ can be abused even more than C, it has all the problems C has and then adds more.
« Last Edit: March 28, 2014, 12:50:43 am by miguelvp »
 

Offline miguelvp

  • Super Contributor
  • ***
  • Posts: 5550
  • Country: us
Re: the c-semantics project is aimed against - C undefined behavior -
« Reply #44 on: March 28, 2014, 01:11:21 am »
There are lies, damn lies and the TIOBE index.

Do a simple google search and you will find out why this TIOBE index is worst than useless, it doesn't use any scientific principals to gather OR interpret the data.

Any professor who presents TIOBE index as anything than something that should be ignored isn't qualified to be teaching anyone anything!

Interesting site
http://langpop.com/

Btw I use C++ at work 99.999% of the time, so I'm not one of those that think C is better, not for what I do for a living anyways. The other 0.001% minor things in python.

At home playing with small processors, assembler, C, VHDL and Verilog.

C++ is great for very complex systems (meaning hundreds of thousands of lines of code) that run on computers with lots of resources i.e. cycles, memory, bandwidth, etc

C is great for medium sized non complex programs (under 100,000 lines of code), also for well defined kernels in general they are for more compact and efficient systems that are close to the OS or are the OS themselves. git for example is pure C and more efficient that C++ implementations of source control.

Assembly can't be beat when you want the most out of a system, and it's not any more difficult than C.

Python, well, that's a flexible beast for anything else on a system that has enough resources as well, it has everything plus the kitchen sink but I wouldn't use it for anything other than non time critical things. But I could do the time critical things in C++, C or even assembly and import the module to python if needed. Still only for systems with lots of resources. I find python to be a good candidate for embedding a console to an application so you can allow the user to create new behavior instead of making them compile plug-ins.
 

Offline dfmischler

  • Frequent Contributor
  • **
  • Posts: 548
  • Country: us
Re: the c-semantics project is aimed against - C undefined behavior -
« Reply #45 on: March 28, 2014, 01:43:19 am »
- That your program and data memory space is the same address space
I can assure you that early C implementations could easily deal with separate instruction and data spaces (on some PDP-11 models, for example).  Nothing in ANSI C has changed that.  grumpydoc is correct that there is no guaranteed ability to read instruction memory by type punning (and this does not work when there are separate instruction and data spaces).

 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: the c-semantics project is aimed against - C undefined behavior -
« Reply #46 on: March 28, 2014, 02:33:23 am »
I can assure you that early C implementations could easily deal with separate instruction and data spaces (on some PDP-11 models, for example).  Nothing in ANSI C has changed that.  grumpydoc is correct that there is no guaranteed ability to read instruction memory by type punning (and this does not work when there are separate instruction and data spaces).

Yep, I am sure that is the case. I also learnt C on Real mode 8086, with all it's segment registers - _near, _far and _huge pointers and so on. I remember the joy of moving to flat 32-bit address spaces :-)

It isn't only trying to read instruction space. One behaviou that gets a lot of people is excess RAM usage by are constant strings / character arrays that should be held in ROM or FLASH. During initalisation the strings have to get copied from the program ROM address space into RAM in case it is ever updated.

Makes perfect sense if you really know what is going on at the lowest levels...


Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 

Offline miguelvp

  • Super Contributor
  • ***
  • Posts: 5550
  • Country: us
Re: the c-semantics project is aimed against - C undefined behavior -
« Reply #47 on: March 28, 2014, 02:45:07 am »
I also learnt C on Real mode 8086, with all it's segment registers - _near, _far and _huge pointers and so on. I remember the joy of moving to flat 32-bit address spaces :-)
Circa 1988
Code: [Select]
void far *finddata()
{
   void far *ptr;
   int *aux;

   aux = settextstyle ;
   aux = aux + 21;
   ptr = ((void far *) (((unsigned long)(_DS) << 16) | (unsigned)(*aux)));
   return (ptr);
}

Yes, that's how you accessed the Data Segment back then, let kcc figure that code out :-DD
« Last Edit: March 28, 2014, 02:47:19 am by miguelvp »
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: the c-semantics project is aimed against - C undefined behavior -
« Reply #48 on: March 28, 2014, 02:52:48 am »
Yes, that's how you accessed the Data Segment back then, let kcc figure that code out :-DD

And don't get me started on using code overlays!

However, one thing I dearly miss is A000:0000-FFFF, where you could write pixels directly to the frame buffer. Oh the good old days!
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 

Offline miguelvp

  • Super Contributor
  • ***
  • Posts: 5550
  • Country: us
Re: the c-semantics project is aimed against - C undefined behavior -
« Reply #49 on: March 28, 2014, 03:41:21 am »

And don't get me started on using code overlays!

However, one thing I dearly miss is A000:0000-FFFF, where you could write pixels directly to the frame buffer. Oh the good old days!

I had a hercules card so I was bound to B000

From my never released ZX Spectrum emulator that took the emulated frame buffer and displayed it on my hercules monitor, file date 2/24/1989:

Code: [Select]
typedef union {
   unsigned char far *ptr;
   struct {
      unsigned offset;
      unsigned segment;
   } addr;
} memtype ;

...

void refreshscr(unsigned segment)
{
   memtype source,destination;
   int XINC,YINC,x,y;


   source.addr.segment = segment;
   destination.addr.segment = 0xB000;
   YINC = 4;
   XINC = 90;

   for (y=0;y<192;y++) {
       source.addr.offset = 0x4000 + (unsigned)256*(8*(y/64)+y%8)
       + (unsigned)32*((y%64)/8);
       destination.addr.offset = 8192*(y%YINC) + XINC*(y/YINC);
       for (x=0;x<32;x++)
   destination.ptr[x] = source.ptr[x];
   }
}

Yeah, that could be optimized more but hey this is 25 years ago, the C code is 300 lines with comments, the assembler to emulate the z80 was 2000 lines with comments as well. Made my own cross assembler and typed the full disassembly mnemonics from a book that produced the rom. Also had an assembly routine that read the cassette tapes directly to an original IBM PC via the audio DIN connector, respecting the timings of the tape.

Back on topic before I destroy this thread going down on memory lane.

The C language only defines the compiler itself, but those guys are trying to define stdlib those are just functions. I know is not a good thing but I did write many applications that will self modify on purpose, like a run-time compiler that will take a math expression compile it in memory with 8087 code (actually the emulated opcodes that would be changed to 8087 ones if the math co-processor was available) and call it from the main program. Data, program space who cares if you can do it then why not?

So what will kcc do about that?
Let me exploit the language the way I want.

« Last Edit: March 28, 2014, 04:02:00 am by miguelvp »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf