Delphi code
var
BookNode, EntityNode: TXmlNode;
Books: TXmlNodeList;
...
for BookNode in Books do
In CLang compiler in C++Builder
for (auto && BookNode : Books)
How to write this code in a classic compiler?
The Count/RecordCount/Items->Count e.g. property is missing.
I'm using the classic compiler because some components do not support CLang.
The classic compiler does not support C++11, so you can't use a range-based for loop. You have to use a traditional for loop instead.
Delphi's for..in loop is based on the concept of an Enumerator (see Iteration Over Containers Using For Statements). However, Delphi's TXMLNodeList does not implement an Enumerator, so you can't use it in a for..in loop.
C++11's range-based for loop is based on the concept of iterators. Embarcadero's CLang compilers implement iterators for many Delphi-style containers that implement a GetEnumerator() method or Count+operator[] properties. See C++ Iterator Support for Delphi Enumerable Types and Containers. In the classic compiler, you would have to use such accesses manually, eg:
for(Iterator iter = list->begin(); iter != list->end(); ++iter)
{
ElementType &elem = *iter;
...
}
for(int index = 0; index < list->Count; ++index)
{
ElementType &elem = (*list)[index]; // or list->Items[index], etc...
...
}
EnumeratorType *enum = list->GetEnumerator();
while (enum->MoveNext())
{
ElementType elem = enum->Current;
...
}
Despite your claim, Delphi's TXMLNodeList DOES have public Count and Nodes[] properties (inherited from the IXMLNodeList interface) for indexing through nodes (Delphi's XML framework predates C++11, after all), eg:
_di_IXMLNodeList Books;
...
for(int i = 0; i < Books->Count; ++i)
{
_di_IXMLNode BookNode = Books->Nodes[i];
...
}
UPDATE: the above was based on an assumption that you were using Embarcadero's XML framework, which has its own TXMLNode and TXMLNodeList classes. Based on your comment that you are actually using VerySimpleXML instead, which has similarly named classes, I looked at its code and see that its TXmlNodeList class derives from Delphi's TObjectList<T> class, which has public Count and Items[] properties. So, you can use those in a for loop, eg:
TXMLNodeList *Books;
...
for(int i = 0; i < Books->Count; ++i)
{
TXMLNode *BookNode = Books->Items[i];
...
}
Related
I am trying to make a TImage move like a DVD logo, but the TImage is not moving.
This is the code I used:
void __fastcall TForm1::DVDLogoTimer(TObject *Sender)
{
image->Left+=xPos; image->Top+=yPos;
if (image->Left <= invisibleHelperObject->Left) xPos=-xPos;
if (image->Top <= invisibleHelperObject->Top) yPos=-yPos;
if (image->Left+image->Width >= invisibleHelperObject->Width) xPos=-xPos;
if (image->Top+image->Height >= invisibleHelperObject->Height) yPos=-yPos;
Label1->Caption = IntToStr(xPos) + " | " + IntToStr(yPos);
}
(X and Y variables are not even changing (stays at 0))
In C++Builder 6 (and the "classic" Borland compiler in modern versions), you can't use compound operators like += with properties. Doing so will read the property value into a temporary and then modify the temporary, but will not assign the temporary back to the property. Using compound operators on properties requires a modern Clang-based compiler:
Differences Between Clang-enhanced C++ Compilers and Previous Generation C++ Compilers, __property: Compound and Chained Assignment
Clang-enhanced C++ compilers support compound assignment of __property, while BCC32 does not.
The objects of the keyword __property are not like fields or members. They should be used in simple assignments.
Although both BCC32 and the RAD Studio Clang-enhanced C++ compilers allow __property to be used in compound assignments such as:
Form1->Caption += DateToStr(Now());
BCC32 only invokes the getter, not the setter. Therefore we recommend that you avoid such constructs when targeting multiple platforms.
None of these compilers support the usage of __property in chained assignment, as in:
Button2->Caption = Button1->Caption = DateToStr(Now()); // Error
So, in your situation, when you invoke image->Left += xPos; for instance, it acts as-if you had written this instead:
//image->Left += xPos;
int temp = image->Left;
temp += xPos;
So, you need to use the + and = operators separately instead, eg:
void __fastcall TForm1::DVDLogoTimer(TObject *Sender)
{
image->Left = image->Left + xPos;
image->Top = image->Top + yPos;
...
}
This is my code:
int foo(int x) {
return x + 1; // I have more complex code here
}
int main() {
int s = 0;
for (int i = 0; i < 1000000; ++i) {
s += foo(42);
}
}
Without -O3 this code works for a few minutes. With -O3 it returns the same result in no time. Clang++, I believe, caches the value of foo(42) (it's a pure function) and doesn't call it a million times. How can I instruct it NOT to apply this particular optimization for this particular function call?
Out of curiosity, can you share why you would want to disable that optimization?
Anyway, about your question:
In your example code, s is never read after the loop, so the compiler would throw the whole loop away. So let's assume that s is used after the loop.
I'm not aware of any pragmas or compiler options to disable a particular optimization in a particular section of code.
Is changing the code an option?
To prevent that optimization in a portable manner, you can look for a creative way to compute the function call argument in a way such that the compiler is no longer able to treat the argument as constant. Of course the challenge here is to actually use a trick that does not rely on undefined behavior and that cannot be "outsmarted" by a newer compiler version.
See the commented example below.
pro: you use a trick that uses only the language that you can apply selectively
con: you get an additional memory access in every loop iteration; however, the access will be satisfied by your CPU cache most of the time
I verified the generated assembly for your particular example with clang++ -O3 -S. The compiler now generates your loop and no longer caches the result. However, the function gets inlined. If you want to prevent that as well, you can declare foo with __attribute__((noinline)), for example.
int foo(int x) {
return x + 1; // I have more complex code here
}
volatile int dummy = 0; // initialized to 0 and never changed
int main() {
int s = 0;
for (int i = 0; i < 1000000; ++i) {
// Because of the volatile variable, the compiler is forced to assume
// that the function call argument is different for each loop
// iteration and it is no longer able to use a cached result.
s += foo(42 + dummy);
}
}
Is there a fast (native) method to search for a sequence in a Uint8List?
///
/// Return index of first occurrence of seq in list
///
int indexOfSeq(Uint8List list, Uint8List seq) {
...
}
EDIT: Changed List<int> into Uint8List
No. There is no built-in way to search for a sequence of elements in a list.
I am also not aware of any dart:ffi based implementations.
The simplest approach would be:
extension IndexOfElements<T> on List<T> {
int indexOfElements(List<T> elements, [int start = 0]) {
if (elements.isEmpty) return start;
var end = length - elements.length;
if (start > end) return -1;
var first = elements.first;
var pos = start;
while (true) {
pos = indexOf(first, pos);
if (pos < 0 || pos > end) return -1;
for (var i = 1; i < elements.length; i++) {
if (this[pos + i] != elements[i]) {
pos++;
continue;
}
}
return pos;
}
}
}
This has worst-case time complexity O(length*elements.length). There are several more algorithms with better worst-case complexity, but they also have larger constant factors and more expensive pre-computations (KMP, BMH). Unless you search for the same long list several times, or do so in a very, very long list, they're unlikely to be faster in practice (and they'd probably have an API where you compile the pattern first, then search with it.)
You could use dart:ffi to bind to memmem from string.h as you suggested.
We do the same with binding to malloc from stdlib.h in package:ffi (source).
final DynamicLibrary stdlib = Platform.isWindows
? DynamicLibrary.open('kernel32.dll')
: DynamicLibrary.process();
final PosixMalloc posixMalloc =
stdlib.lookupFunction<Pointer Function(IntPtr), Pointer Function(int)>('malloc');
Edit: as lrn pointed out, we cannot expose the inner data pointer of a Uint8List at the moment, because the GC might relocate it.
One could use dart_api.h and use the FFI to pass TypedData through the FFI trampoline as Dart_Handle and use Dart_TypedDataAcquireData from the dart_api.h to access the inner data pointer.
(If you want to use this in Flutter, we would need to expose Dart_TypedDataAcquireData and Dart_TypedDataReleaseData in dart_api_dl.h https://github.com/dart-lang/sdk/issues/40607 I've filed https://github.com/dart-lang/sdk/issues/44442 to track this.)
Alternatively, could address https://github.com/dart-lang/sdk/issues/36707 so that we could just expose the inner data pointer of a Uint8List directly in the FFI trampoline.
First off, I want to thank Rustan and the whole community for the work you put on Dafny. It is an amazing language!
I am working on my Master's thesis which is about formal verification of virtual machines using Dafny.
This is how I define (a stripped version of) a virtual machine:
class VM
{
var v: array<bv8>;
var I: bv16;
var memory: array<bv8>;
predicate Valid()
reads this
{
v.Length == 16
&& memory.Length == 0x0FFF
}
constructor Init()
ensures Valid()
{
v := new bv8[16];
I := 0;
memory := new bv8[0x0FFF];
}
}
So far so good. I have a few methods that mutate the state of this machine. In particular, here's one:
method parse_opcode_registers(vm: VM, opcode: bv16)
requires vm.Valid()
modifies vm`I, vm.v
{
var i: int := 0;
var bound := ((opcode & 0x0F00) >> 8) as int;
if opcode & 0xF0FF == 0xF065
{
while i < bound && vm.I as int < vm.memory.Length
decreases bound - i
{
vm.v[i] := vm.memory[vm.I];
i := i + 1;
vm.I := vm.I + 1;
}
}
}
This passes Dafny's verification. However, the issue occurs when there exists a caller for this method. Namely, the following code will produce an error call may violate context's modifies clause:
method Main() {
var vm := new VM.Init();
parse_opcode_registers(vm, 0xF018);
}
Any hints would be appreciated.
You need to add ensures fresh(v) to the Init constructor of VM.
Basically, the problem is that Dafny is worried because parse_opcode_register claims to modify vm.v, but Dafny isn't sure where vm.v came from. Remember that Dafny analyzes the program one method at a time, so it does not look inside the constructor Init while analyzing Main. Instead, Dafny only looks at the pre/postcondition. That's why adding fresh(v) to the postcondition fixes it.
The meaning of fresh(blah) is that blah was freshly allocated during the execution of the method.
For more, see the FAQ question about modifies clauses.
I have a for loop in action script which I'm trying to use to dynamically create variable.
Example
for( i = 0 ; i < 3 ; i++)
{
var MyVar+i = i;
}
after this for loop runs, i would like to have 3 variables named MyVar1, MyVar2, MyVar3. I know the code above will give you a syntax error, but that is just to illustrate what I am trying to do. Any takers?
The primary reason i'm doing this is because I'm having scope problems noted here in this other unanswered Action Script question: How to pass variables into inline functions in Action Script 2
Thanks!
I could be wrong (I haven't done AS2 for a long while), but I think you can do this using array syntax:
for( i = 0 ; i < 3 ; i++)
{
this["myVar"+i] = i;
}
and then for variable access:
var foo = this["myVar0"] //etc
First answer is correct, but if you make the class dynamic (ie. new members can be created dynamically) ...
dynamic class ClassName { // etc. }
... then you can reference the variable in normal syntax:
var foo = this.myVar0;
You won't be able to access the variable at all without 'this' whether the class is dynamic or not.