why this complicated structure constants is internal linkage - constants

as you know, constants defaults to internal linkage.
const int Buf = 1000; // defaults to internal linkage
Buf can be defined in a header file, it's visible only within the files where it is defined and cannot be seen at link time by other translation units.
however, if some complicated structure constants are defined as below:
- constants.h
const complicatedClass myObject("I'm a const object","internal linkage",5);
complicatedClass definition:
class complicatedClass
{
private :
char* charArry;
std::string strTemp;
static int numbers;
int mSize;
public:
complicatedClass();
complicatedClass(char* pChrArry, std::string temp, int size);
~complicatedClass();
public:
void print() const;
std::string getStrTemp() const;
};
it seems that compile must create storage for complicated structure constants, thus it should be external linkage. however, everything is ok when this constants header file (constants.h) was included in multiple files. I assume the linker error should be raised, myObject shouldn't be defined in many places(in multiple files)
can anyone explain this issue? thanks in advance.

Internal linkage does not mean no storage. Rather it means the variable is not visible in other translation units.
In C++ const allows the compiler to either create storage for the variable or not. Whether it does so or not depends on whether it needs it.
So in your example the compiler will create storage for myObject only if it needs it (which it probably does) because it is const. Also because it is const, myObject will also have internal linkage which means each translation unit will have its own copy of myObject if storage is required.
A simple test you can do to see this in action is to take the address of myObject in a number of different translation units (effectively in different cpp files) and print it out. This will do two things: force storage to be created for myObject even if it wasn't already; and you will see two different addresses because of the internal linkage.

Related

Can one derive Swift functions from the (C convention) functions in a dylib using knowledge from their prototypes in the C .h file?

I have some dynamic libraries making available over 200 functions via C calling conventions. I have no access to the source. I'd like to provide these as functions callable by Swift.
Currently I am making each function from the dylibs available via code like this:
public func mainInit() -> Int64 {
let dllMainInitPointer = getFunctionPointer(libHandle, "DllMainInit")
typealias DllMainInitFunction = PtrDllMainInit
let dllMainInit = unsafeBitCast(dllMainInitPointer, to: DllMainInitFunction.self)
return dllMainInit()
}
where PtrDllMainInit is obtained by Swift interpreting the C function prototypes in the header file, in this case:
typedef int64_t (*PtrDllMainInit)(void);
. . .
extern PtrDllMainInit DllMainInit;
which works. But (a) it returns the result of the function, and I'd rather it return the function itself, so it can be called independently, and (b) every use repeats executing the boilerplate code.
It seems that this boilerplate, in every function, could possibly be factored out. (I already factored, behind getFunctionPointer, calling dlsym and checking for missing symbols). Most of the dylib functions are generally more complex than this example, having multiple parameters; writing 200+ functions, like above, is time consuming and prone to error.
Ideally, I'd like a way auto-generate assignments that provide the Swift functions, using the dylib handle, the symbol name, and the C prototype; something like the following:
dllMainInit = magicFunction(libHandle, "DllMainInit", PtrDllMainInit)
In addition to factoring out repetition, one-liners (or, maybe two-liners) like this can be generated simply by processing the header file into this form.
Ultimately, allowing something of this form in the C headers:
typedef int (*PtrProp2)(int64_t key, double time, double llh[3]);
to be converted to a Swift function (closure?), and invoked, thusly:
let prop2 = magicFunction(libHandle, "DllProp2", PtrProp2)
. . .
prop2(id, hours, &vector)
This is a bit tangled, I hope I've explained it well enough.
Edit: Well, this works for simple function I started with:
public func mainInit() -> () -> Int64 {
unsafeBitCast(getFunctionPointer(libHandle,
"DllMainInit"),
to: PtrDllMainInit.self)
}
The parameters of the returned closure can be derived from the .h file. I'll see if this mechanism hold up for more complications.

Reverse C++/WinRT ABI parameter order for MIDL 3.0 array parameter?

I have an existing interface that I'm trying to define using MIDL 3.0. One of it's methods has this C++ signature:
HRESULT GetArray(struct FOO** outArray, uint32_t* outSize);
I tried translating this to IDL like so:
namespace Examples {
struct Foo {
Int32 n1;
Int32 n2;
};
interface IExample {
void GetArray(out Foo[] array);
}
}
However, the resulting C++/WinRT ABI has the parameters in the opposite order:
template <> struct abi<Examples::IExample>{ struct type : IInspectable
{
virtual HRESULT __stdcall GetArray(uint32_t* __arraySize, struct struct_Examples_Foo** array) noexcept = 0;
};};
This does make sense considering that is the recommended order. Unfortunately, I don't have the ability to change the parameter order of the existing interface. Instead, I figured I might be able to work around it using "classic" style:
namespace Examples {
[uuid("d7675bdc-7b6e-4936-a4a0-f113c1a3ef70"), version(1)]
interface IExample {
HRESULT GetArray(
[out, size_is(, *size)] Foo** array,
[out] unsigned long* size
);
}
}
But, this is rejected by the MIDL compiler:
MIDL4058: [msg]The size parameter of an array parameter must appear directly before the array parameter. [context]size
How do I write this interface in IDL in such a way that results in the correct ABI?
WinRT has a strict ABI definition for the ordering of array parameters, and as you have discovered it is (size, pointer) and not the other way around. There is no way to change this, since all the projections (such as .NET, JavaScript, and C++/CX) expect this order and would fail catastrophically if passed in the wrong order.
If you cannot change the ordering, can you write a wrapper class that exposes the correct ordering and simply forwards the calls onto your existing code with the parameters reversed?
Failing that, there is another way to support this if you only care about C++ (and maybe C# clients). That is, rather than defining a WinRT interface for this method, you can define a classic-COM interface and have your WinRT object implement that interface as well. Then the clients of your WinRT object QI for that COM interface and can pass the arguments in the order you require.

C++ Is "class Name*" a class pointer?

I was watching an unreal tutorial and encountered this line of code:
class UStaticMeshComponent* Pickup;
It is a forwards declaration.
I have been studying c++ for a while and have not encountered anything like this before. I know about pointers and references, but I never seen this format: class Name*. Are we creating a class pointer to another class? I tried searching for class names followed by a *, but the only result that appeared were about data types and pointers.
public:
APickUp ();
virtual void BeginPlay () override;
virtual void tick ( float DeltaSeconds );
private:
class UStaticMeshComponent* Pickup;
class UStaticMeshComponent* Pickup;
This declares the type class UStaticMeshComponent and also declares the variable Pickup of type pointer to UStaticMeshComponent. So the above code is more or less equivalent with:
class UStaticMeshComponent;
UStaticMeshComponent* Pickup;
Because at this point you don't have the definition of UStaticMeshComponent (just the declaration), UStaticMeshComponent is considered an incomplete type. There are a few things you can do with an incomplete type. One of them is declare pointers to them.
When you are only using a pointer to a type, the type is not required to be complete, so this works fine even if UStaticMeshComponent has not been defined. That means when this header is included in one of your cpp files, it should compile a bit faster than if Pickup.h were to include the header where UStaticMeshComponent is defined.
This speed up could be substantial depending on how big that header is, and how many times the include is avoided during compilation.
The big confusion here is the difference between:
class UStaticMeshComponent* Pickup;
and
class UStaticMeshComponent *Pickup;
and even this:
class UStaticMeshComponent * Pickup;
, as in the example http://www.cplusplus.com/doc/tutorial/classes/#pointers_to_classes .
The difference is - bad practice. All supposed to mean the same thing but only the second example is correct, yet all of them work.
At least according to this:
https://users.ece.cmu.edu/~eno/coding/CppCodingStandard.html
place the * close to variable name not pointer type
I am a novice, I might be wrong. Please correct me if i am wrong.

Static fields/methods in e

Is there any technical reason I am missing for which e doesn't have static fields/methods?
I've looked up the LRM and there is no mention of anything like this. There are workaround (like this one: http://www.specman-verification.com/index.php?entry=entry060612-105347), but I don't find it a particularly clean approach as it's not nicely encapsulated.
Good question. There should be no such technical reasons to not have it, and it might be a good idea to add static members to e structs. Its semantics would just need to be carefully considered, because of the aspect-oriented features of e, which are irrelevant to some other languages that have static members (for example, one question that would need to be answered is whether static methods can be extended, e.g., with is also or not).
However, it doesn't seem very critical to me, because a static field is, effectively, no more than a global field (or method, or any other kind of struct member) that belongs to a given struct's namespace. So, even without having static members, an easy workaround is to add such a member to global (or to sys), and make sure that its name has a prefix that makes it clear to "belong" to a given struct.
There is an important point, though, which does make static members more than just a member of global. In e, like in C++, there are template types. A static member of a template would be something that, on the one hand, is shared by all instance objects of a given template instance type, but on the other hand, would exist separately for each template instance (each one of which being a separate struct).
Not sure if the port-based workaround suggested at the above link is any better. I see it as an overkill.
Actually, in my previous answer I am missing an important point, which does make static members more than just a member of global.
In e, like in C++, there are template types. A static member of a template would be something that, on the one hand, is shared by all instance objects of a given template instance type, but on the other hand, would exist separately for each template instance (each one of which being a separate struct).
By the way static struct members were added to the language in Specman v15.2. They are handy especially in configuration structs that are well, static:
extend packet_s {
static max_address : uint = 0x1000;
};
-- Change max_address for all instances
on xxx { packet_s::max_address = 0x2000; };
A static field can't be generated, physical(%) or used in when subtypes. Here's some comments from the teamspecman blog : Static members in e
I think the main reason why e doesn't have static struct members yet is the fact that you always have global and sys singletons as well as top unit of your specific module (which means better encapsulation), where the 'static' information can be placed. There is no special technical reason for that, besides some complexity in defining exact semantics.
As a syntactic sugar for the unit access, you can always wrap it with very basic single-word macro - it will not be completely seamless, because this magic word will always be required vs. natively visible static struct members of 'me', but still very easy to use.

How does the assembler handle classes and objects, and how are they stored in RAM and the executable?

How does an assembler handle classes and objects when a programme is compiled? And how is this stored in RAM and the executable file?
At first, memory is allocated according to the class' size, for example 20 bytes. In these 20 bytes, all variables of the class are stored. But there are two problems:
How do pointers to classes work?
How does a called method know which object it belongs to?
Could you explain this to me? (If using example code, I prefer Objective-C, C++ and x86 Assembly)
The assembler has no clue what a class is, it only assembles machine code, which the occasional macro tossed in. For all intents and purposes a class is merly a struct with an optional vftable, with all the handling and class 'special features' (virtualism, polymorphism, inheiritanc etc) being done in the intermediate stage, when IR code is created. Memory would be allocated the same as a struct, variable, array or any other data 'blob' (statically or dynamically, taking alignment, const'ness and packing into account), except for the support code to handle stack & static based dtor unwinding(done again at the IR level), ctors, and static initialization(though static initialization can happen for more than class objects). I suggest you give the dragon book a read through (the first eight chapters would cover it), to get a clearer picture of how a compiler and assembler work, seeing as these things are not handled by the assembler, but by the compiler front and/or back ends, depending on how the compiler an its IL are structured.
(2) Member functions are rewritten by the compiler. Consider class A as follows.
class A {
int i;
public:
A () : i (0) { }
void f (int a, char *b) { i = a; }
}
Then what the compiler makes of A::f looks something like this (pseudocode):
void A::f (A * const this, int a, char *b) { this->i = a; }
Consider now a call to A::f.
A a;
a.f (25, "");
The compiler generates code similar to this (pseudocode):
A a;
A::f (&a, 25, "");
In other words, the compiler works the hidden this pointer into every non-static member function and each call receives a reference to the instance that it was called upon. This, in particular, means that you can invoke non-static member functions on NULL pointers.
A *a = NULL;
a->f (25, "");
The crash only occurs when you actually reference non-static class member variables.
The resulting crash report also illustrates the answer to question (1). In many cases, you'll not crash on address 0, but an offset of that. That offset corresponds to the offset that the accessed variable has in the memory layout the compiler chose for class A (in this case, many compilers will actually offset it with 0x0 and class A will in memory not be distinguishable from struct A { int i; };). Basically, pointers to classes are pointers to the equivalent C struct. Member functions are implemented as free functions taking an instance reference as first argument. All and any access checks with regard to public, protected and private members is done upfront by the compiler, the generated assembly has no clue about any of those concepts. In fact, early versions of C++ are said to have been sets of clever C macros.
The memory layout (typically) changes a bit when you have virtual functions.