I have the following code in Object Oriented Turbo Pascal (an example). And also, some questions for you guys, who have the knowledge of Turbo Pascal - because I can't find any answers.
type PMyNumber =^TMyNumber;
TMyNumber = object(TObject)
Number1:real;
Number2:real;
constructor Init(x,y:real);
end;
Question #1
I see code like new(PMyNumber,Init(-4,0)) - is it some type of an object constructor ?
Question #2
someVariable := PMyNumber(MyColl[myIndex]^.At(j))^.Number1
I try to view the value of the MyColl[myIndex]^.At(j). To do so, I open the Evaluate/modyfy window, but after click on Evaluate button, the I get the following error - what's wrong ?
moreover (I don't think the ) char is needed here:
Question #3
how to read the pointer variable value ?
Yes, Init() is the name of the constructor.
You cannot evaluate a function call (At() is a member function of TMyNumber inherited from TObject).
If mean how to interpret the Pascal pointer notation: a leading '$' means hexadecimal value. The first value ($888F) is the segment and the second value ($8) is the offset within the segment. (Assuming you understanding the concept segments in a 16-environment.) If you mean how to read the value of a pointer at runtime: Use seg() to get the segment and ofs() to get the offset, like seg(MyColl[myindex]) and ofs(MyColl[myindex]).
Related
I am new to IDL and find the KEYWORD_SET difficult to grasp. I understand that it is a go no go switch. I think its the knocking on and off part that I am having difficulty with. I have written a small program to master this as such
Pro get_this_done, keyword1 = keyword1
WW=[3,6,8]
PRINT,'WW'
print,WW
y= WW*3
IF KEYWORD_Set(keyword1) Then BEGIN
print,'y'
print,y
ENDIF
Return
END
WW prints but print, y is restricted by the keyword. How do I knock off the keyword to allow y to print.
Silly little question, but if somebody can indulge me, it would be great.
After compiling the routine, type something like
get_this_done,KEYWORD1=1b
where the b after the one sets the numeric value to a BYTE type integer (also equivalent to TRUE). That should cause the y-variable to be printed to the screen.
The KEYWORD_SET function will return a TRUE for lots of different types of inputs that are basically either defined or not zero. The IF loop executes when the argument is TRUE.
Keywords are simply passed as arguments to the function:
get_this_done, KEYWORD1='whatever'
or also
get_this_done, /KEYWORD1
which will give KEYWORD1 the INT value of 1 inside the function. Inside the function KEYWORD_SET will return 1 (TRUE) when the keyword was passed any kind of value - no matter whether it makes sense or not.
Thus as a side note to the question: It often is advisable to NOT use KEYWORD_SET, but instead resort to a type query:
IF SIZE(variable, /TNAME) EQ 'UNDEFINED' THEN $
variable = 'default value'
It has the advantage that you can actually check for the correct type of the keyword and handle unexpected or even different variable types:
IF SIZE(variable, /TNAME) NE 'LONG' THEN BEGIN
IF SIZE(variable, /TNAME) EQ 'STRING' THEN $
PRINT, "We need a number here... sure that the cast to LONG works?"
variable = LONG(variable)
ENDIF
This question already has answers here:
Go: invalid operation - type *map[key]value does not support indexing
(2 answers)
Closed 9 months ago.
I try to loop through a map, that I pass as a pointer to a function, but I can't find a way to access the elements. This is the code:
func refreshSession(sessions *map[string]Session) {
now := time.Now()
for sid := range *sessions {
if now.After(*sessions[sid].timestamp.Add(sessionRefresh)) {
delete( *sessions, sid )
}
}
}
Line 4 in this example return following compile error:
./controller.go:120: invalid operation: sessions[sid] (type *map[string]Session does not support indexing)
I tried brackets, but it had no effect. If I take away all reference operators (* &) then it compiles fine.
How must I write this?
You don't need to use a pointer with a map.
Map types are reference types, like pointers or slices
If you needed to change the Session you could use a pointer:
map[string]*Session
De-reference the map first and then access it (Example on play):
(*sessions)[sid]
It's also noteworthy that maps are actually reference types and therefore there is a very limited use-case of using pointers. Just passing a map value to a function will not copy the content. Example on play.
You are not taking into account the precedence of *.
*session[sid] really means *(session[sid]), that is, first indexing the pointer to map (hence the error), then dereferencing it.
You should use (*session)[sid].timestamp to first dereference the pointer to the map and then access it using the key.
I'm trying to read some example code about implicit creation of QVariants from enum values.
About the following line of code:
QVariant::fromValue<Qt::PenStyle>(Qt::SolidLine)
I don't really understand what is the purpose of Qt::PenStyle in the above expression.
I think Qt::SolidLine is unique.
The syntax is OK?
Shouldn't it be something like:
QVariant::fromValue(Qt::SolidLine)
?
Sorry if this question seems dumb.
You can use this form:
1) QVariant::fromValue(Qt::SolidLine)
QVariant::fromValue(const T & value) is a template method. When you call a template method or function you can specify for what type of argument this method should be called. If you don't do that a compiler tries to do it for you. That is why 1) is equal to this:
2) QVariant::fromValue<Qt::PenStyle>(Qt::SolidLine)
But you can call this method for int and pass enum value (if you are not at c++11):
3) QVariant::fromValue<int>(Qt::SolidLine)
or even force creating of QPen:
4) QVariant::fromValue<QPen>(Qt::SolidLine)
EDIT:
If someone is suprised by 4 and want to know how it works: it is the same as if there was a method (actually it is created during the compilation):
QVariant::fromValue(const QPen& pen);
When you call this method with Qt::SolidLine compiler uses an implicit constructor QPen(Qt::PenStyle style) to create a new temporary QPen object and pass it as an argument to the method fromValue.
I am using custom LLVM pass where if I encounter a store to
where the compiler converts the value to a Constant; e.g. there is an explicit store:
X[gidx] = 10;
Then LLVM will generate this error:
aoc: ../../../Instructions.cpp:1056: void llvm::StoreInst::AssertOK(): Assertion `getOperand(0)->getType() == cast<PointerType>(getOperand(1)->getType())->getElementType() && "Ptr must be a pointer to Val type!"' failed.
The inheritance order goes as: Value<-User<-Constant, so this shouldn't be an issue, but it is. Using an a cast on the ConstantInt or ConstantFP has no effect on this error.
So I've tried this bloated solution:
Value *new_value;
if(isa<ConstantInt>(old_value) || isa<ConstantFP>(old_value)){
Instruction *allocInst = builder.CreateAlloca(old_value->getType());
builder.CreateStore(old_value, allocInst);
new_value = builder.CreateLoad(allocResultInst);
}
However this solution creates its own register errors when different type are involved, so I'd like to avoid it.
Does anyone know how to convert a Constant to a Value? It must be a simple issue that I'm not seeing. I'm developing on Ubuntu 12.04, LLVM 3, AMD gpu, OpenCL kernels.
Thanks ahead of time.
EDIT:
The original code that produces the first error listed is simply:
builder.CreateStore(old_value, store_addr);
EDIT2:
This old_value is declared as
Value *old_value = current_instruction->getOperand(0);
So I'm grabbing the value to be stored, in this case "10" from the first code line.
You didn't provide the code that caused this first assertion, but its wording is pretty clear: you are trying to create a store where the value operand and the pointer operand do not agree on their types. It would be useful for the question if you'd provide the code that generated that error.
Your second, so-called "bloated" solution, is the correct way to store old_value into the stack and then load it again. You write:
However this solution creates its own register errors when different type are involved
These "register errors" are the real issue you should be addressing.
In any case, the whole premise of "converting a constant to a value" is flawed - as you have correctly observed, all constants are values. There's no point storing a value into the stack with the sole purpose of loading it again, and indeed the standard LLVM pass "mem2reg" will completely remove such a sequence, replacing all uses of the load with the original value.
Given below is some code in ada
with TYPE_VECT_B; use TYPE_VECT_B;
Package TEST01 is
procedure TEST01
( In_State : IN VECT_B ;
Out_State : IN OUT VECT_B );
function TEST02
( In_State : IN VECT_B ) return Boolean ;
end TEST01;
The TYPE_VECT_B package specification and body is also defined below
Package TYPE_VECT_B is
type VECT_B is array (INTEGER range <>) OF BOOLEAN ;
rounded_data : float ;
count : integer ;
trace : integer ;
end TYPE_VECT_B;
Package BODY TYPE_VECT_B is
begin
null;
end TYPE_VECT_B;
What does the variable In_State and Out_State actually mean? I think In_State means input variable. I just get confused to what actually Out_State means?
An in parameter can be read but not written by the subprogram. in is the default. Prior to Ada 2012, functions were only allowed to have in parameters. The actual parameter is an expression.
An out parameter implies that the previous value is of no interest. The subprogram is expected to write to the parameter. After writing to the parameter, the subprogram can read back what it has written. On exit the actual parameter receives the value written to it (there are complications in this area!). The actual parameter must be a variable.
An in out parameter is like an out parameter except that the previous value is of interest and can be read by the subprogram before assignment. For example,
procedure Add (V : Integer; To : in out Integer; Limited_To : Integer)
is
begin
-- Check that the result wont be too large. This involves reading
-- the initial value of the 'in out' parameter To, which would be
-- wrong if To was a mere 'out' parameter (it would be
-- uninitialized).
if To + V > Limited_To then
To := Limited_To;
else
To := To + V;
end if;
end Add;
Basically, every parameter to a function or procedure has a direction to it. The options are in, out, in out (both), or access. If you don't see one of those, then it defaults to in.
in means data can go into the subroutine from the caller (via the parameter). You are allowed to read from in parameters inside the routine. out means data can come out of the routine that way, and thus you are allowed to assign values to the parameter inside the routine. In general, how the compiler accomplishes the data passing is up to the compiler, which is in accord with Ada's general philosophy of allowing you to specify what you want done, not how you want it done.
access is a special case, and is roughly like putting a "*" in your parameter definition in Cish languages.
The next question folks usually have is "if I pass something large as an in parameter, is it going to push all that data on the stack or something?" The answer is "no", unless your compiler writers are unconsionably stupid. Every Ada compiler I know of under the hood passes objects larger than fit in a machine register by reference. It is the compiler, not the details of your parameter passing mechanisim, that enforces not writing data back out of the routine. Again, you tell Ada what you want done, it figures out the most efficient way to do it.