February 23, 2005

David Medlock wrote:
> John Reimer wrote:
> 
>>
>> I should point out, though, that initializing static/global values to null/0 is not necessary since D does that automatically on program start.
> 
> 
> In doing some stuff with floating point math I was stumped until I noticed the default value for float/double/real is NaN.
> (I am not sure why, though I am sure there is a good reason for this)

Walter (and most of us?) think that initialising floats to something
obviously "wrong" is better than letting them be zero. The idea
being that you're not supposed to use uninitialised variables
anyway, so forgetting to do this jumps into your face at once.

(I'm under the impression that this would've be done with ints
too, but there's unfortunately no way to Officially Define a NAN
for the int types.)

Forgetting to initialise something that's zero is less obvious.
And happens a lot, especially in the future, when a lot of
VB-folks etc. come here.

Initialising floats to NANs is cheaper and easier than having
the compiler do enormous checks on whether this or that variable
actually _could_ be used before initial assignment in complicated
code.

That is what the IEEE recommends, anyway.

-----------

OT: a little trivia + personal opinion:

Had I designed the IEEE format, I'd have the bit pattern
"all-zeros" represent NAN, so that it would be fiercely
obvious what the intent of NAN is. Well, they didn't. 000000
means +0. (Yeah, plus, not just zero.)

Interestingly, there are several bit patterns that mean
NAN. One of them is all-ones.

Oh, and then there are _two_ different NANs, one for (eh,
might I say) regular NANs, and the other for Serious NANs.

They're called QNAN and SNAN. The former is pretty much
what would be used if an intermediate result is "not nice",
and the latter for "oh crap" situations. Or at least
_should_ be used.

How exactly they work in D math isn't something I don't
remember having studied.
February 24, 2005
In article <cvhbhn$14r$1@digitaldaemon.com>, John Reimer says...
>
>Ron wrote:
>> The C way of:
>> 
>> void[16] *routines = {
>> 0, 0, 0, 0, 0, 0, 0, 0,
>> 0, 0, 0, 0, 0, 0, 0, 0
>> };
>> 
>> does NOT work. I get the message:
>> "Error: a struct is not a valid initializer for a void[16]*"
>> 
>> Same thing with a char array (same way, just w/ string data), but the error
>> message is:
>> "Error: a struct is not a valid initializer for a char[32]*"
>> 
>> How do you init these arrays?
>> 
>> --Ron
>> 
>> 
>
>I'm not sure what you intended here.
>
>The above is a single pointer to an array of 16 void types.  So you won't succeed in trying to assign the array values to a single pointer.
>
>So doing this is valid:
>
># void[16] *routines = null;
>
>But if you wanted to assign 16 values to an array of 16 void pointers, try this:
>
># void*[16] routines = null;
>
>The above is a nifty shorthand for assigning "null" to all 16 variables in the array.
>
>You could do it the long way like this:
>
># // Global variable
>#
># void*[16] routines = [
>#  null, null, null, null, null, null, null, null,
>#  null, null, null, null, null, null, null, null
># ];
>
>The above is a static initializer, so it only works for global variables or static variables (variables lasting the lifetime of the program: the local equivalent to a global variable).  Notice that brackets are used instead of braces.
>
>If you wanted to do the above inside a function, you would do:
>
># static void*[16] routines = [
>#  null, null, null, null, null, null, null, null,
>#  null, null, null, null, null, null, null, null
># ];
>
>I hope that helps you.
>
>- John R.

Thanks John, that did work... *routines was a pointer to an array of 16 void pointers. I'm having a little trouble in the same area with a char[32] *array (pointer to 32 strings of var. length). The error I get is:

"d/isrs.d: In function `_staticCtor':
d/isrs.d:0: error: aggregate value used where an integer was expected"

The code looks like this:

char[32] *exception_messages;  // global

static this()
{
*exception_messages[0] = cast(char)"Division By Zero";
*exception_messages[1] = cast(char)"Debug";
*exception_messages[2] = cast(char)"Non Maskable Interrupt";
*exception_messages[3] = cast(char)"Breakpoint";
*exception_messages[4] = cast(char)"Into Detected Overflow";
*exception_messages[5] = cast(char)"Out of Bounds";
*exception_messages[6] = cast(char)"Invalid Opcode";
*exception_messages[7] = cast(char)"No Coprocessor";
*exception_messages[8] = cast(char)"Double Fault";
*exception_messages[9] = cast(char)"Coprocessor Segment Overrun";
*exception_messages[10] = cast(char)"Bad TSS";
*exception_messages[11] = cast(char)"Segment Not Present";
*exception_messages[12] = cast(char)"Stack Fault";
*exception_messages[13] = cast(char)"General Protection Fault";
*exception_messages[14] = cast(char)"Page Fault";
*exception_messages[15] = cast(char)"Unknown Interrupt";
*exception_messages[16] = cast(char)"Coprocessor Fault";
*exception_messages[17] = cast(char)"Alignment Check";
*exception_messages[18] = cast(char)"Machine Check";
*exception_messages[19] = cast(char)"Reserved";
*exception_messages[20] = cast(char)"Reserved";
*exception_messages[21] = cast(char)"Reserved";
*exception_messages[22] = cast(char)"Reserved";
*exception_messages[23] = cast(char)"Reserved";
*exception_messages[24] = cast(char)"Reserved";
*exception_messages[25] = cast(char)"Reserved";
*exception_messages[26] = cast(char)"Reserved";
*exception_messages[27] = cast(char)"Reserved";
*exception_messages[28] = cast(char)"Reserved";
*exception_messages[29] = cast(char)"Reserved";
*exception_messages[30] = cast(char)"Reserved";
*exception_messages[31] = cast(char)"Reserved";
}

Thanks in advance,
--Ron


February 24, 2005
> char[32] *exception_messages;  // global
> 
> static this()
> {
> *exception_messages[0] = cast(char)"Division By Zero";
> }

<snip>

try this
char*[32] exception_messages;
static this()
{
exception_messages[0] = "Division by Zero";
}

having your type as "char[][32] exception_messages" also works.

Brad
February 24, 2005
On Thu, 24 Feb 2005 20:16:07 +0000 (UTC), Ron wrote:

[snip]
> The code looks like this:

Or maybe ...

import std.stdio;

private char[][] exception_messages;
char[] GetMessageText(int id)
{
   if (id >= 0 && id < exception_messages.length)
      return exception_messages[id].dup;
   else
      return "";
}

static this()
{
   exception_messages ~= "Division By Zero";
   exception_messages ~= "Debug";
   exception_messages ~= "Non Maskable Interrupt";
   exception_messages ~= "Breakpoint";
   exception_messages ~= "Into Detected Overflow";
   exception_messages ~= "Out of Bounds";
   exception_messages ~= "Invalid Opcode";
   exception_messages ~= "No Coprocessor";
   exception_messages ~= "Double Fault";
   exception_messages ~= "Coprocessor Segment Overrun";
   exception_messages ~= "Bad TSS";
   exception_messages ~= "Segment Not Present";
   exception_messages ~= "Stack Fault";
   exception_messages ~= "General Protection Fault";
   exception_messages ~= "Page Fault";
   exception_messages ~= "Unknown Interrupt";
   exception_messages ~= "Coprocessor Fault";
   exception_messages ~= "Alignment Check";
   exception_messages ~= "Machine Check";
 }

 void main()
 {
 writefln("%s", GetMessageText(4));
 }

This makes sure that outside code cannot change the text of any message, and makes it easy to expand the list of messages in future. Also, no pointers involved.

-- 
Derek
Melbourne, Australia
February 24, 2005
In article <1el83535hd3ja$.xafk5jfa77v5$.dlg@40tude.net>, Derek says...
>
>On Thu, 24 Feb 2005 20:16:07 +0000 (UTC), Ron wrote:
>
>[snip]
>> The code looks like this:
>
>Or maybe ...
> 
>import std.stdio;
>
>private char[][] exception_messages;
>char[] GetMessageText(int id)
>{
>   if (id >= 0 && id < exception_messages.length)
>      return exception_messages[id].dup;
>   else
>      return "";
>}
> 
>static this()
>{
>   exception_messages ~= "Division By Zero";
>   exception_messages ~= "Debug";
>   exception_messages ~= "Non Maskable Interrupt";
>   exception_messages ~= "Breakpoint";
>   exception_messages ~= "Into Detected Overflow";
>   exception_messages ~= "Out of Bounds";
>   exception_messages ~= "Invalid Opcode";
>   exception_messages ~= "No Coprocessor";
>   exception_messages ~= "Double Fault";
>   exception_messages ~= "Coprocessor Segment Overrun";
>   exception_messages ~= "Bad TSS";
>   exception_messages ~= "Segment Not Present";
>   exception_messages ~= "Stack Fault";
>   exception_messages ~= "General Protection Fault";
>   exception_messages ~= "Page Fault";
>   exception_messages ~= "Unknown Interrupt";
>   exception_messages ~= "Coprocessor Fault";
>   exception_messages ~= "Alignment Check";
>   exception_messages ~= "Machine Check";
> }
>
> void main()
> {
> writefln("%s", GetMessageText(4));
> }
>
>This makes sure that outside code cannot change the text of any message, and makes it easy to expand the list of messages in future. Also, no pointers involved.
>
>-- 
>Derek
>Melbourne, Australia

Thanks Derek, but unfortunately I can't use the standard libs... I have to implement the std lib myself... Writing a toy OO kernel for a prog. class project.

--Ron


February 24, 2005
In article <1el83535hd3ja$.xafk5jfa77v5$.dlg@40tude.net>, Derek says...
>
>On Thu, 24 Feb 2005 20:16:07 +0000 (UTC), Ron wrote:
>
>[snip]
>> The code looks like this:
>
>Or maybe ...
> 
>import std.stdio;
>
>private char[][] exception_messages;
>char[] GetMessageText(int id)
>{
>   if (id >= 0 && id < exception_messages.length)
>      return exception_messages[id].dup;
>   else
>      return "";
>}
> 
>static this()
>{
>   exception_messages ~= "Division By Zero";
>   exception_messages ~= "Debug";
>   exception_messages ~= "Non Maskable Interrupt";
>   exception_messages ~= "Breakpoint";
>   exception_messages ~= "Into Detected Overflow";
>   exception_messages ~= "Out of Bounds";
>   exception_messages ~= "Invalid Opcode";
>   exception_messages ~= "No Coprocessor";
>   exception_messages ~= "Double Fault";
>   exception_messages ~= "Coprocessor Segment Overrun";
>   exception_messages ~= "Bad TSS";
>   exception_messages ~= "Segment Not Present";
>   exception_messages ~= "Stack Fault";
>   exception_messages ~= "General Protection Fault";
>   exception_messages ~= "Page Fault";
>   exception_messages ~= "Unknown Interrupt";
>   exception_messages ~= "Coprocessor Fault";
>   exception_messages ~= "Alignment Check";
>   exception_messages ~= "Machine Check";
> }
>
> void main()
> {
> writefln("%s", GetMessageText(4));
> }
>
>This makes sure that outside code cannot change the text of any message, and makes it easy to expand the list of messages in future. Also, no pointers involved.


This is why we want to see a compiler-enforced 'readonly' attribute for content ~ to enforce CoW :)

That aside -- you can also do this, Ron:

struct Msg {int id; char[] text;}

static const Msg[] =
[
{0, "Division By Zero"},
{1, "Debug"},
{2, "Non Maskable Interrupt"},
{3, "Breakpoint"},
{4, "Into Detected Overflow"},
{5, "Out of Bounds"},
];


- Kris


February 24, 2005
On Thu, 24 Feb 2005 21:53:37 +0000 (UTC), Ron wrote:

> In article <1el83535hd3ja$.xafk5jfa77v5$.dlg@40tude.net>, Derek says...
>>
>>On Thu, 24 Feb 2005 20:16:07 +0000 (UTC), Ron wrote:
>>
>>[snip]
>>> The code looks like this:
>>
>>Or maybe ...
>> 
>>import std.stdio;
>>
>>private char[][] exception_messages;
>>char[] GetMessageText(int id)
>>{
>>   if (id >= 0 && id < exception_messages.length)
>>      return exception_messages[id].dup;
>>   else
>>      return "";
>>}
>> 
>>static this()
>>{
>>   exception_messages ~= "Division By Zero";
>>   exception_messages ~= "Debug";
>>   exception_messages ~= "Non Maskable Interrupt";
>>   exception_messages ~= "Breakpoint";
>>   exception_messages ~= "Into Detected Overflow";
>>   exception_messages ~= "Out of Bounds";
>>   exception_messages ~= "Invalid Opcode";
>>   exception_messages ~= "No Coprocessor";
>>   exception_messages ~= "Double Fault";
>>   exception_messages ~= "Coprocessor Segment Overrun";
>>   exception_messages ~= "Bad TSS";
>>   exception_messages ~= "Segment Not Present";
>>   exception_messages ~= "Stack Fault";
>>   exception_messages ~= "General Protection Fault";
>>   exception_messages ~= "Page Fault";
>>   exception_messages ~= "Unknown Interrupt";
>>   exception_messages ~= "Coprocessor Fault";
>>   exception_messages ~= "Alignment Check";
>>   exception_messages ~= "Machine Check";
>> }
>>
>> void main()
>> {
>> writefln("%s", GetMessageText(4));
>> }
>>
>>This makes sure that outside code cannot change the text of any message, and makes it easy to expand the list of messages in future. Also, no pointers involved.
>>
>>-- 
>>Derek
>>Melbourne, Australia
> 
> Thanks Derek, but unfortunately I can't use the standard libs... I have to implement the std lib myself... Writing a toy OO kernel for a prog. class project.

?HUH? What std lib? I just used the writefln() to debug this snippet. You don't have use it. However, after seeing Kris' version, I'd go with his. Much neater than mine. ;-)


-- 
Derek
Melbourne, Australia
25/02/2005 9:17:08 AM
February 24, 2005
Assuming these are /static/ values, you could also just do:

private static const char[][] exception_messages = [
	"Division By Zero",
	"Debug",
	"Non Maskable Interrupt",
	"Breakpoint",
	"Into Detected Overflow",
	"Out of Bounds",
	"Invalid Opcode",
	"No Coprocessor",
	"Double Fault",
	"Coprocessor Segment Overrun",
	"Bad TSS",
	"Segment Not Present",
	"Stack Fault",
	"General Protection Fault",
	"Page Fault",
	"Unknown Interrupt",
	"Coprocessor Fault",
	"Alignment Check",
	"Machine Check"
];

-- Chris S
February 25, 2005
This should work for what I believe you were trying to do:

void*[16] routines = [
null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null
];

or

void *routines[16] = [
null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null
];

'[.,.,.]' is for arrays, '{.,.,.}' is for structs.

See: http://digitalmars.com/d/arrays.html for more info. on the syntax for arrays, arrays of ptrs, ptrs to arrays (like you actually had), init. of arrays, etc.

- Dave

In article <cvhaar$31av$1@digitaldaemon.com>, Ron says...
>
>The C way of:
>
>void[16] *routines = {
>0, 0, 0, 0, 0, 0, 0, 0,
>0, 0, 0, 0, 0, 0, 0, 0
>};
>
>does NOT work. I get the message:
>"Error: a struct is not a valid initializer for a void[16]*"
>
>Same thing with a char array (same way, just w/ string data), but the error
>message is:
>"Error: a struct is not a valid initializer for a char[32]*"
>
>How do you init these arrays?
>
>--Ron
>
>


1 2
Next ›   Last »