This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What does the caret mean in C++/CLI?
In C++/CLR, what does a hat character ^ do?
I created my first Win form application in Visual Studio C++, and browsing through the code saw something that I cannot understand:
private: System::Windows::Forms::Button^ button1;
What is the meaning of ^ sign in this line? I understand * and & but never seen ^ in definition of an object.
Have a look here this is not just C++ but C++/CLI
In C++/CLI the only type of pointer is the normal C++ pointer, and the .NET reference types are accessed through a "handle", with the new syntax ClassName^ instead of ClassName*. This new construct is especially helpful when managed and standard C++ code is mixed; it clarifies which objects are under .NET automatic garbage collection and which objects the programmer must remember to explicitly destroy.
It designates a garbage collected pointer. The normal C++ version is * for pointers, C++/CLI uses ^ to differentiate between managed and unmanaged. It also uses a different keyword to allocate the memory.
int* plain_cpp = new int;
delete plain_cpp; // unmanaged
int^ cpp_cli = gcnew int;
// managed, no delete possible
It's equivalent to a pointer (*) in C++/CLI. One key difference is that it is garbage collected, since C++/CLI is managed.
^ means it is a CLR type and not a C++ native type
Related
Summary
After declaring an array for some object type where the type doesn't use an interface that derives from COM's IDispatch interface (& so isn't properly set-up to enable [OLE] Automation's late-binding technology), trying to assign the array to a Variant variable doesn't work according to my expectations.
Specifically, what appears to happen is that an integral pointer to the array is assigned to the Variant variable, instead of a copy of the array.
Can anyone explain such behaviour? Is it standard behaviour of the VBA 7.1 language? [EDIT-A1] Is it that VBA's Variant type can't handle such arrays? [EDIT-A2]
[EDIT-A1] - Currently (4/6/19), it's looking like it's a bug.
[EDIT-A2] - No, as the internal procedure parameters for ByRef Variant arguments can properly point to such arrays, if such arrays are passed as the values for such arguments.
Background
More details on what appears to be happening
After inspecting various memory addresses & pointers, what appears to be happening is that when assigning such arrays to Variant variables, the Long (or LongPtr) pointers to the 'VB safe array pointers' of the arrays, are instead being assigned. This is contrary to the array-copying behaviour documented here in the VBA language specification as being expected behaviour. I deduced such pointer assignment was taking place after reviewing VB6 documentation on VB arrays & their memory layout, stored here.
My research into whether issue has been previously documented
I've searched the internet, the Office VBA Reference documentation, & the VBA language specification to see whether this problem has been documented by anyone else. The only place I've found where this problem may have already been partly documented is in a Stack Overflow answer posted here. Unfortunately, the post doesn't say much about the problem.
Specific array types that I have tested this issue with
I have experienced this issue with arrays of the following object types that use interfaces not deriving from IDispatch:
stdole.IUnknown *
stdole.IFont
mscoree.CorRuntimeHost †
mscorlib.AppDomain †
mscorlib.Type
* From OLE Automation COM type library in stdole2.tlb.
† From COM type library for the .NET framework v4.0.30319.
More on what an object type that uses an interface not deriving from IDispatch, is
Such object types are vbDataObject types. Unfortunately, the current VBA documentation on the vbDataObject constant is inaccurate. I'm in the process of updating the documentation, & you can see my updated definition for the constant here.
[EDIT - COM specification link removed as it is no longer relevant.]
Regarding arrays of other object types
Arrays of vbObject types (COM object types that support [OLE] Automation late-binding technology) appear to be assigned to Variant variables in a straight-forward & expected manner - array is copied and directly assigned.
VBE used to crash when inspecting such arrays using a VBE watch
A potentially related issue is to do with a bug that used to occur when a VBE watch expression was placed on an array of a type that used an interface not deriving from IDispatch. The bug used to cause the VBE to unexpectedly crash. This bug appears to have been fixed by Microsoft within the last month.
Software versions
Software | Version
-------------------------+--------------- VBA | 7.1 ‡-------------------------+--------------- Microsoft Excel | 2016 §-------------------------+--------------- Microsoft Windows (OS) | 8.1 ¶
‡ Full text for version is "Retail 7.1.1088"—the latest version.§ More specifically, the latest version & build (released on 3rd June 2019, version 1905, build 11629.20214), & also earlier build numbers 11629.20196 & 11601.20204 (first was released on 14th May 2019).
¶ ver.exe program prints "Microsoft Windows [Version 6.3.9600]".
Code
Reprex:
Dim MyArray() As stdole.IUnknown ' Type from OLE Automation
' COM type library in stdole2.tlb.
Dim MyVariant As Variant
MyVariant = MyArray
I expected MyVariant to store a copy of the MyArray array.
Instead, in the 32-bit version of VBA, MyVariant stores a Long value that appears to be a pointer to MyArray.
Debugging issue
Click here
for VBA code to assist in debugging issue.
This question already has an answer here:
What is the purpose of static keyword in array parameter of function like "char s[static 10]"?
(1 answer)
Closed 8 years ago.
As we know, the keyword static has multiple meanings in C. C99 added the possibility of legally writing
void foo (int arr[static 50])
{
// ...
}
which adds to the confusion, and C++ has static member variables and functions.
This would not be so troublesome if all the uses could be connected in some way, but I find it hard to find that link for some of the cases. Particularly why the static keyword should be used to modify visibility (linkage), or what on earth it's got to do with an array's minimum amount of elements.
So is there a historical reason for the abuse of the static keyword, or is there a secret link under the hood that connects all of its uses?
Adding new keywords to a language breaks backwards compatibility. So static gets used where its use might possibly mean something ( int arr[static 50] vs int arr[auto 50] or int arr[extern 50] ) and cannot syntactically appear in that location based its use in previous versions.
Though in that case adding a not_less_than context sensitive keyword in that position would not break previous code, it would add another keyword (so simple text editors which are keyword aware but not syntax aware would not know whether or not it is a keyword), and break the 'keywords are not context sensitive' simplification made in C.
There is a very simple way of remembering of all 3 C++ meanings of static I'm aware of. static means "pretty much like global variable/function but only available directly in scope of..."
"...this file" if it is in global scope.
"...this function" if it is in a function (including member functions). Note that if you make classes and lambdas in a function, they are still in this scope. Lambda with an empty capture can access static variable of its "parent" function.
"...this class" if it is in a class (including those declared with struct). This case is slightly different as you can access the variable/function through an object or by prefixing, but this is a little like asking the class or its object to provide you access to it, and it in fact can be denied (with private). So the access isn't "direct".
In case of the presented C99 array syntax, this is something completely different and I assume it was there to not introduce new keywords, as others suggest.
static's original meaning in C++ is actually deprecated, replaced with unnamed namespaces. The only way static is actually used in current C++ code is to be non-member.
I think the reasons are different for the different usages that this keyword has. If we take the function scope and file scope use as of classical C for granted (they are at least similar concepts) the first addition off topic is the static in C++ to name a global member of a class.
I guess here the shortcut was just that "static" and "global" seemed to be close enough and early C++ was very careful not to introduce new keywords that would break existing code. So they took an existing one that could not appear in that context.
For the C99 add-on for array parameters things are different, I think, because static is not the only addition, here. You may also have type qualifiers (const and volatile) that qualify the implicit pointer:
void toto1(char str[const 5]);
void toto2(char*const str);
define compatible prototypes. I can only speculate that the choice of the storage class specifier static for the purpose that you mention (minimum length of the array) was seen as a natural extension of that syntax. Also probably it easily proved that this use was compatible with the rest of language, by arguing where a type qualifier may be used to extend the language, a storage class specifier can't do much harm.
A camel is a horse designed by committee.
http://en.wikipedia.org/wiki/Design_by_committee
ADDED:
Committee members involved in the design are conservative, and are more interested in not breaking existing C++ code than the potential elegance of new code.
This question already has answers here:
Enabling VLAs (variable length arrays) in MS Visual C++?
(5 answers)
Closed 5 years ago.
I understand in VS all variables must be declared at the top of a block, but if I want a VLA, ie. if I wanted to do something like this:
int result = runalgorithm();
int vla[result];
the code above is invalid, because vla must be declared at the top. What is a good solution for this, other than creating an arbitrarily large array?
You cannot. VLA is supported in C99 and later standards. (Support is mandatory in C99; it is optional in C11.) C89 does not have the VLA concept or support for it.
You can choose dynamic memory allocation, instead. have a look at malloc() and family for your reference.
Remember, if you want to use dynamic memory (allocation), you have to free() the allocated memory once you're done using it.
MSVC doesn't support VLAs. Recent versions of MSVC do support declarations mixed with statements in C compiles (I think this started with VS 2013).
I'm having trouble translating from some C declarations to Delphi XE2 for calling functions in a DLL. I translated all the function declarations from a Visual Basic source file, but in testing them I ran in to problems. Some functions returned Long values, but debugging my code I observed that the functions involved returned values that weren't right. Then I turned to the original code in C, and there I found the root of my troubles: At some point in the original C code there is this declaration:
typedef struct { } __RSI_CHANNEL;
typedef __RSI_CHANNEL FAR* RSI_CHANNEL;
Now, some functions return RSI_CHANNEL; those functions return values like this:
return (RSI_CHANNEL)ws;
And ws is declared as:
rsiChannel FAR* ws = new FAR rsiChannel;
rsiChannel is a typedef struct. So far, so good...by now I guess some of you may have recognized this as PIMPL idiom. Ok, according to the source code comments, I should have to save that return value (RSI_CHANNEL) and test against NULL, and pass it through function calls untouched...nothing more...so my take is it should be implemented in Delphi as Pointer. But it doesn't work. Something like this:
Type
RSI_CHANNEL = Pointer;
...{ later in implementation block }...
Function rsiInitWsock(HostName : PAnsiChar; port : Long) : RSI_CHANNEL; stdcall; external 'rsidll32';
No compile errors, no runtime errors. If I call this function, I get Nil.
¿Any idea how this could be implemented in Delphi XE2? and, ¿what I'm doing wrong? thanks in advance.
Additional details:
Delphi XE2 (target: Win32)
Windows 7 x64
I found the problem; it didn't had to do with my code, it was right since the beginning; it has to do with a ping function in the DLL, it worked on a laptop but it doesn't want to work with a desktop PC (both Win7), and when it doesn't work it breaks subsequent function calls to the DLL (why, I don't know...yet). Anyway, it wasn't a full solution, but #DavidHeffernan was the first to come up with the idea that the problem was someplace else, so I'm accepting his answer mainly because it pointed me in the right direction. Thanks to everyone!
As described, your handling of RSI_CHANNEL is correct. Declaring it as Pointer is the appropriate action. To make type safety stronger you could define a distinct type rather than an alias:
Type
RSI_CHANNEL = type Pointer;
If the port parameter is really WORD then that maps to Word in Delphi.
As to your problem, it lies elsewhere. The translation of RSI_CHANNEL is accurate.
Since RSI_CHANNEL is a typed pointer in the C code, I would declare a similar typed pointer in Delphi to match, instead of using an untyped Pointer (this is also inline with modern Delphi versions using STRICT to avoid untyped pointers in Win32 API handle types like HWND, etc):
type
RSI_CHANNEL = ^__RSI_CHANNEL;
__RSI_CHANNEL = record
end;
Function rsiInitWsock(HostName : PAnsiChar; port : WORD) : RSI_CHANNEL; stdcall; external 'rsidll32';
This question already has answers here:
Is it better to use C void arguments "void foo(void)" or not "void foo()"? [duplicate]
(6 answers)
in c: func(void) vs. func() [duplicate]
(2 answers)
Closed 8 years ago.
Having done most of my dev deeds in C++ and C#, I find the habit in C of specifying an empty parameter list with "void" a bit peculiar, but seeing it in "trustworthy sources" makes me assume it's required-ish. The question is why?
To clarify, in for instance Visual Studio, I cannot with any combination of enabled C compiler switches, and disabled C++ compiler switches, get even as much as a compiler warning when writing this:
void foo_bar();
Then, what is it that makes it necessary-ish to instead declare it with this:
void foo_bar(void);
Is it just old C standardese that is lingering that is not needed with later C standards?
Backstory:
When declaring functions in C (any symbol actually) you need declare everything in the proper order (declare a function before using it) otherwise you'll get errors regarding undefined symbols.
Forward declaration of functions allows you to accomplish this by declaring only the function signature (without the body). This allows the compiler to identify function names (symbols) and later use them before they are completely defined.
When using forward declarations to export the publicly accessible functions of a library (in your public header files) you will declare the entire signature so that users of your library will know what parameters are expected.
When using forward declarations for your own internal use you (sometimes) won't need to declare the entire signature of the function, only the return type and name will suffice -- no parameters. Only when you finally define the function will you specify the parameter list.
Direct answer:
Yes it's just old C standardese and nothing more. Because the same C standardese says that empty brackets means an unknown number of parameters (not necessarily 0).
Related reading:
This question I've asked some time ago tries to fathom (like you) the utility of declaring functions with "an unknown number of parameters" -- apparently in a very misconstrued way.