Suppose we create a list class with a function that eliminates elements from position a to position b.
The class is supposed to be used by other programmers (like std::list).
Example:
list values : {0,1,2,3,4,5,6} and we call this function with (begin = 2, end = 5).
This would change the list to being {0,1,6}
If the user calls the function with end > size of the list, it's better to just reassign end = size and delete until the last one or launch an exception like out_of_range?
This is a good question about programming standards. If someone calls your method with end > size, they have technically gone against the prerequisites of your function. It is possible the programmer called your function thinking it did something else, such as eliminated all list values in between the values they gave. If your function does not throw an exception, they will not know anything has gone wrong until there is a logical error later. The best practice if given incorrect parameters is to throw an exception, explaining what they did wrong. It puts more of a challenge on the person using your function, but it saves them more trouble later.
For input argument for rightIndex > list.size(), you have a few options to provide:
ERROR: Exception (Array index out of range)
WARNING: rightIndex is truncated to end of the list at Line 5:56
ASSERTION FAILED (Error): assert(rightIndex >= 0 && rightIndex < list.size());
Reference Mismatch Error: Reference provided by rightIndex is not matched with the function deleteBetween(leftIndex, rightIndex){ ... }
Segmentation Fault (SIGSEGV): Invalid memory reference and access violation, trying to read or write from/to a memory area that you have access to.
How does the method Sort of the class TList work? Does this method only sort in a way that the elements of the list only ascend/descend?
Please, have a look at the code below.
Type
PInteger = ^Integer;
Function Compare(Item1, Item2 : Pointer) : Integer;
Begin
if PInteger(Item1)^ > Pinteger(Item2)^ then Result:= 1
else if PInteger(Item1)^ < PInteger(Item2)^ then Result:= -1
else Result:= 0;
End;
{ And, for instance, somewhere we call the method }
List.Sort(Compare);
Now the thing is, after i compile the code, it works well, the list is sorted in a way that the elements ascend. But i don't understand the following line:
PInteger(item1)^ // What does this represent?
And what item1, item2 pointers point to? Do they not need to be initialized?
First what PInteger(item1)^ does/represent?
Item1 is a Pointer, the address of an item stored in the TPointerList.
PInteger is a typed pointer, this means that this pointer points to an address where it is expected to find an integer (four bytes).
^ the dereferencing symbol, you can use this with pointers to tell the compiler that you want to use the data stored in the address that the pointer is currently pointing to
PInteger(item1)^ you are performing a typecast. in other words you are telling the compiler to treat the pointer Item1 as if it was PInteger then you dereference it to use its data/value stored at the address Item1
Now back to your code. Your function expects two pointers to Items (Integers) from the list which then you compare the data stored in those address (by dereferencing). This means that the list is responsible for the pointers given to your function, in fact if the ItemCount is less than 1 your function will not be executed.
Note: you need to understand that this function will fail if the pointers are pointing to something other than integers (or give an undefined behavior).
What happened ?
var n interface{} = 2
var pn = &n
var pf = (*int64)(unsafe.Pointer(pn))
fmt.Println(pf)
fmt.Println(pn)
fmt.Println(*pn) // 2
fmt.Println(*pf) // not 2
*pf = 9
fmt.Println(*pn) //error invalid memory address or nil pointer dereference
fmt.Println(*pf) // 9
My question is Why is *pf not equal to *pn and error ?
Thanks for your reply.
n is of an interface{} type, so in memory it is represented by a struct of 2 values: a type and data. The type comes first. So you dereference it and interpret as a number.
*pf = 9 breaks that structure, so next time you try to dereference it - the runtime fails.
For simplicity let’s think we have 64-bit machine.
n is pair of 2 words of 64-bit: first is a pointer to a variable, second is a pointer to information about type - so called itab.
When you get a value pointed by pn compiler knows you want value of an interface, so it goes by the first pointer and returns int value. Compiler thinks pf is a pointer to float64 . So it lets. You to overwrite first word in the interface n with some likely incorrect address (equal to binary value of 9.0). Next time you see the value in the interface compiler uses incorrect address. And return some garbage or even SegFault.
That’s why it’s called unsafe.Pointer and is not recommended to use. Until you have very serious concerns.
An interface value contains information about the type of the data it contains and then the actual value (or a pointer to the value). When you cast a pointer to the interface to *int64, the *int64 will point into some random data in the interface value (which today happens to be a pointer to the information about the type, but this is allowed to change, this part of the language is not covered by the compatibility guarantee). When you then overwrite that data, things break, unsafe is called unsafe for a reason.
*pf is not equal to *pn because they have different types even though they might contain the same bit pattern.
I'm trying to to get a list of three items with their relevant information based on a collection of information:
product(I):-
I = [_,_,_,_], %Type,Brand,Category,Value
cheaper(item(apple,_,_),item(_,kay,_,_),I),
cheaper(item(bar,_,_,_),item(_,_,fruit,_),I),
member(item(_,kay,_,2),I),
member(item(apple,granny,_,_),I),
member(item(bar,_,chocolate,_),I),
/* Below not given */
member(item(cracker,_,_,_),I),
member(item(_,_,biscuit,_),I),
member(item(_,_,_,4),I),
member(item(_,_,_,5),I).
cheaper(X,Y,H) :- %Used to determine the item values
item(X,_,_,A),
item(Y,_,_,B),
A<B.
When I try running it I encounter an error:
?- product(I).
ERROR: cheaper/3: Undefined procedure: item/4
Exception: (8) item(item(apple, _G3604, _G3605), _G3651, _G3652, _G3653) ?
I understand that item isn't a procedure, however what can I used for checking the value for apple against the value for bar?
First, the obvious note, you're calling cheaper wrong once:
cheaper(item(apple,_,_),item(_,kay,_,_),I),
↑
Only three values, not four.
If item isn't a procedure, you mustn't call it, but use destructuring.
Also you want those items you're checking with cheaper to be part of the list, right? If so, you'll have to check that. And you can use unification to extract the values that you need:
cheaper(X,Y,I) :-
member(X,I),
member(Y,I),
[item(_,_,_,A),item(_,_,_,B)] = [X,Y],
A<B.
Now you'll get some errors regarding not instantiated argument. That's because you are checking not (yet) set variables if they are greater than each other. To avoid this, move the cheaper/3 calls to the end of your clause body:
product(I):-
I = [_,_,_,_], %Type,Brand,Category,Value
member(item(_,kay,_,2),I),
member(item(_,_,_,4),I),
member(item(_,_,_,5),I),
member(item(apple,granny,_,_),I),
member(item(bar,_,chocolate,_),I),
/* Below not given */
member(item(cracker,_,_,_),I),
member(item(_,_,biscuit,_),I),
cheaper(item(apple,_,_,_),item(_,kay,_,_),I), % note the 4th argument
cheaper(item(bar,_,_,_),item(_,_,fruit,_),I).
With this, you'll get one solution and then it fails with an error. This is, because you only give three values for the price slot and you have four items and prolog will check A > 2.
Sorry, in my other answer I didn't look for what the poster was trying to achieve and I think that this is better than a complete reedit. (glorious SO mods let me know if I'm wrong)
I'm trying to have a device register as an enumeration. Reading from the register has 2 values -> 0 means Done, 1 means Pending. Likewise, writing into the register has 2 values -> 0 has no action and 1 does a reset. So, I wrote the following code
type Soft_Reset is (Done, Pending, No_Action, Reset);
for Soft_Reset use
(Done => 0,
Pending => 1,
No_Action => 0,
Reset => 1);
But this throws an error
gcc-4.6 -c -g -gnatg -ggdb -I- -gnatA /home/sid/tmp/device.adb
device.ads:93:20: enumeration value for "No_Action" not ordered
gnatmake: "/home/sid/tmp/device.adb" compilation error
Is it possible for a enumeration to have duplicate values?
I don't think so. But I think it would be more elegant for you to create two enumerated types indicating the one that corresponds to the possible readable values of the register and the other one which corresponds to the writable values.
Something like:
type Register_Status is (Done, Pending) -- Values that can be read
type Soft_Reset is (No_Action, Reset) -- Values that can be written
Gneuromante's post at the bottom is a direct answer to your question.
Another option would be to rename the values. An enumeration value can be renamed as a function:
type Soft_Reset is (Done, Pending);
for Soft_Reset use
(Done => 0,
Pending => 1);
function No_Action return Soft_Reset renames Done;
function Reset return Soft_Reset renames Pending;
No, you can't use the same values for different enumerations representations. But there's a bit more to it than just not being able to use the same values, as the values must be "distinct" and "satisfy the predefined ordering relation of the type", i.e. be in ascending order. RM 13.4(6/2).
Arjun's suggestion of using two distinct types for this purpose is excellent. It both eliminates your specific problem and makes clear the distinction between read codes and write codes.