I'm currently trying to reduce the size of my main function in a GLSL OpenGL ES shader on iOS. Therefore I extracted some helper functions and declared and compiled them in a different shader object. Afterwards I wanted to re-link them back together by using glAttachShader before linking the program that then is used for rendering. All the setup is already done, unfortunately the shader containing my main function won't compile since it can't find the reference to the functions declared in a separate shader. How do I tell the compiler to include the references?
There is some mixed up terminology in your question. There are two related but different constructs involved here:
A function declaration (aka prototype), which only declares the return type, function name, and arguments. It has the form:
returnType functionName(type0 arg0, type1 arg1, ..., typen argn);
A function definition, which has all parts of the declaration, as well as the body that implements the function. It has the form:
returnType functionName(type0 arg0, type1 arg1, ..., typen argn) {
// do some computation
return returnValue;
}
If you split off function implementations into different shaders, the function definition is in that separate shader that contains the actual code for the function. But you will still need a declaration in the shader that contains the main function, or any other shader that calls it.
Once the function is declared, you can call it, even if the implementation is in a different shader. From the spec:
All functions must be either declared with a prototype or defined with a body before they are called.
Related
I am currently writing a wrapper for a native C++ class in CLI/C++. I am on a little GamePacket class at the moment. Consider the following class:
public ref class GamePacket
{
public:
GamePacket();
~GamePacket();
generic<typename T>
where T : System::ValueType
void Write(T value)
{
this->bw->Write(value);
}
};
I want that I'm able to call the function as following in C#, using my Wrapper:
Packet.Write<Int32>(1234);
Packet.Write<byte>(1);
However, I can't compile my wrapper. Error:
Error 1 error C2664: 'void System::IO::BinaryWriter::Write(System::String ^)' : cannot convert argument 1 from 'T' to 'bool'
I don't understand this error, where does the System::String^ comes from. I'm seeing a lot of overloads of the Write() method, does CLI/C++ not call the correct one, and if so, how can I make it call the correct one?
Reference MSDN: http://msdn.microsoft.com/en-us/library/system.io.binarywriter.write(v=vs.110).aspx
Templates and generics don't work the same.
With templates, the code gets recompiled for each set of parameters, and the results can be pretty different (different local variable types, different function overloads selected). Specialization makes this really powerful.
With generics, the code only gets compiled once, and the overload resolution is done without actually knowing the final parameters. So when you call Write(value), the only things the compiler knows is that
value can be converted to Object^, because everything can
value derives from ValueType, because your constraint tells it
Unfortunately, using just that information, the compiler can't find an overload of Write that can be used.
It seems like you expected it to use Write(bool) when T is bool, Write(int) when T is int, and so on. Templates would work like that. Generics don't.
Your options are:
a dozen different copies of your method, each of which has a fixed argument type that can be used to select the right overload of BinaryWrite::Write
find the overload yourself using reflection, make a delegate matching the right overload, and call it
use expression trees or the dynamic language runtime to find and make a delegate matching the right overload, and then you call it
I came across an example for a C-function declared as:
static inline CGPoint SOCGPointAdd(const CGPoint a, const CGPoint b) {
return CGPointMake(a.x + b.x, a.y + b.y);
}
Until now, I declared utility C-functions in .h files and implemented them in .m files, just like this:
CGPoint SOCGPointAdd(const CGPoint a, const CGPoint b) {
return CGPointMake(a.x + b.x, a.y + b.y);
}
I can use this function "inline" anywhere I want and it should also be "static" because it's not associated with any object, like an Objective-c method. What is the point / advantage of specifying "static" and "inline"?
inline does not mean you can use the function “inline” (it is normal to use functions inside other functions; you do not need inline for that); it encourages the compiler to build the function into the code where it is used (generally with the goal of improving execution speed).
static means the function name is not externally linked. If the function were not declared static, the compiler is required to make it externally visible, so that it can be linked with other object modules. To do this, the compiler must include a separate non-inline instance of the function. By declaring the function static, you are permitting all instances of it to be inlined in the current module, possibly leaving no separate instance.
static inline is usually used with small functions that are better done in the calling routine than by using a call mechanism, simply because they are so short and fast that actually doing them is better than calling a separate copy. E.g.:
static inline double square(double x) { return x*x; }
If the storage class is extern, the identifier has external linkage and the inline definition also provides the external definition. If the storage class is static, the identifier has internal linkage and the inline definition is invisible in other translation units.
By declaring a function inline, you can direct the compiler to integrate that function's code into the code for its callers (to replace the complete code of that function directly into the place from where it was called). This makes execution faster by eliminating the function-call overhead. That's why inline functions should be very short.
In C, inline means that it is an inline definition. It doesn't have internal linkage, it has no linkage. It never reaches the linker, which means that if the compiler doesn't use that inline definition to inline every single reference to the function in the compilation unit, then there will be a local linker error if a symbol with the same name (C uses unmangled identifiers) with external linkage is not exported by another translation unit in the compilation. The actual inlining of references to the function by the compiler is exclusively controlled by the optimisation flag or __attribute__((always_inline))
There is no difference between static inline and static, both do not inline the function, and provide the function in the assembly output on -O0 as an internal linkage symbol to the linker, and both inline and optimise out the inclusion of the function in the assembly output on -O1. static inline does have one quirk in that you can use a non-static inline prototype before it, except this prototype is ignored and isn't used as a forward declaration (but using a non-static prototype before a static function is an error).
inline (GCC <5.0, which used -std=gnu90 / gnu89 as default) / extern inline (GCC 5.0 onwards, which uses -std=gnu11): This is a compiler only inline definition. Externally visible function emittance (in the assembly output for use of the assembler and linker) for this inline definition does not occur. If all references to the function in the file are not actually inlined by the compiler (and inlining occurs on higher optimisation levels or if you use __attribute__((always_inline)) inline float func()), then there will be a local linker error if the compiler does not emit the external definition to the linker (and if a symbol with the same name with external linkage is not exported by another translation unit). This allows for an inline definition and an out-of-line function of the same symbol to be defined separately, one with inline and the other out-of-line, but not in the same translation unit as the compiler will confuse them, and an out of line definitition will be treated as a redefinition error. Inline definitions are only ever visible to the compiler and each translation unit can have their own. Inline definitions cannot be exported to other files because inline definitions do not reach the linking stage. In order to achieve this at compile-time, the inline definition can be in a header file and included in each translation unit. This means that the use of inline is a compiler directive and extern/static refer to the out-of-line version produced for the linker. If the function is not defined in the translation unit, it cannot be inlined because it's left to the linker. If the function is defined but not inline, then the compiler will use this version if it decides to inline
extern inline (GCC <5.0) / inline (GCC >5.0): an externally visible function is emitted for this inline definition regardless of whether it is inlined or not meaning this specifier can only be used in one of the translation units. This is intuitively the opposite of 'extern'
static inline: locally visible out-of-line function is emitted by the compiler to the assembly output with a local directive for the assembler for this compiler inline definition, but may be optimised out on higher optimisation levels if all the functions are able to be inlined; it will never allow a linker error to result. It behaves identically to static because the compiler will inline the static definition on higher optimisation levels just like static inline.
An inline function that isn't static shouldn't contain non-const static storage duration variables or access static file-scope variables, this will produce a compiler warning. This is because the inline and out-of-line versions of the function will have distinct static variables if the out-of-line version is provided from a different translation unit. The compiler may inline some functions, not emit a local symbol to be linked to those references, and leave the linkage to the linker which might find an external function symbol, which is assumed to be the same function as it has the same identifier. So it reminds the programmer that it should logically be const because modifying and reading the static will result in undefined behaviour; if the compiler inlines this function reference, it will read a fresh static value in the function rather than the one written to in a previous call to the function, where that previous reference to the function was one that wasn't inlined, hence the variable that was written to in the previous call would have been one provided by a different translation unit. In this instance, it results in a copy local to each translation unit and a global copy and it is undefined as to which copy is being accessed. Making it const ensures that all the copies are identical and will never change with respect to each other, making the behaviour defined and known.
Using an inline / extern inline prototype before/after a non-inline definition means that the prototype is ignored.
Using an inline prototype before an inline definition is how to prototype an inline function without side effects, declaring an inline prototype after the inline definition changes nothing unless the storage specifier changes.
Using an extern inline / extern / regular prototype before/after an inline definition is identical to an extern inline definition; it is a hint that provides an external out-of-line definition of the function, using the inline definition.
Using extern inline / inline on a prototype without a definition in the file but it is referenced in the file results in inline being ignored an then it behaves as a regular prototype (extern / regular, which are identical)
Using a static inline / static on a prototype without a definition in the file but it is referenced in the file results in correct linkage and correct type usage but a compiler warning saying that the function with internal linkage has not been defined (so it uses an external definition)
Using a regular / extern / extern inline prototype before a static inline or static definition is a 'static declaration of 'func' follows non-static declaration' error; using it after does nothing and they are ignored. Using a static or static inline prototype before/after a static inline definition is allowed. Using an inline prototype before a static inline definition is ignored and will not act as a forward declaration. This is the only way in which static inline differs from static as a regular prototype before a static definition results in an error, but this does not.
Using a static inline prototype before a regular / extern / static / static inline / extern inline definition results in static inline overriding the specifiers and acts as correctly as a forward declaration.
__attribute__((always_inline)) always inlines the function symbol in the translation unit, and uses this definition. The attribute can only be used on definitions. The storage / inline specifiers are unaffected by this and can be used with it.
Inline functions are for defining in header files.Small functions are defined in header files.
It should be static so that it can acess only static members.
I've inherited a piece of custom test equipment with a control library built in a COM object, and I'm trying to connect it to our Tcl test script library. I can connect to the DLL using TCOM, and do some simple control operations with single int parameters. However, certain features are controlled by passing in a C/C++ struct that contains the control blocks, and attempting to use them in TCOM is giving me an error 0x80020005 {Type mismatch.}. The struct is defined in the .idl file, so it's available to TCOM to use.
The simplest example is a particular call as follows:
C++ .idl file:
struct SourceScaleRange
{
float MinVoltage;
float MaxVoltage;
};
interface IAnalogIn : IDispatch{
...
[id(4), helpstring("method GetAdcScaleRange")] HRESULT GetAdcScaleRange(
[out] struct SourceScaleRange *scaleRange);
...
}
Tcl wrapper:
::tcom::import [file join $::libDir "PulseMeas.tlb"] ::char
set ::characterizer(AnalogIn) [::char::AnalogIn]
set scaleRange ""
set response [$::characterizer(AnalogIn) GetAdcScaleRange scaleRange]
Resulting error:
0x80020005 {Type mismatch.}
while executing
"$::characterizer(AnalogIn) GetAdcScaleRange scaleRange"
(procedure "charGetAdcScaleRange" line 4)
When I dump TCOM's methods, it knows of the name of the struct, at least, but it seems to have dropped the struct keyword. Some introspection code
set ifhandle [::tcom::info interface $::characterizer(AnalogIn)]
puts "methods: [$ifhandle methods]"
returns
methods: ... {4 VOID GetAdcScaleRange {{out {SourceScaleRange *} scaleRange}}} ...
I don't know if this is meaningful or not.
At this point, I'd be happy to get any ideas on where to look next. Is this a known TCOM limitation (undocumented, but known)? Is there a way to pre-process the parameter into an appropriate format using tcom? Do I need to force it into a correctly sized block of memory via binary format by manual construction? Do I need to take the DLL back to the original developer and have him pull out all the struct parameters? (Not likely to happen, in this reality.) Any input is good input.
I am using DMD64 D Compiler v2.063.2 on Ubuntu 13.04 64-bit.
I have written a class as below:
class FixedList(T){
// list
private T[] list;
// number of items
private size_t numberOfItems;
// capacity
private size_t capacity;
// mutex
private Mutex listMutex;
// get capacity
#property public size_t Capacity(){ return capacity; }
#property public shared size_t Capacity(){ return capacity; }
// constructor
public this( size_t capacity ){
// initialise
numberOfItems = 0;
this.capacity = capacity;
writeln("Cons Normal");
}
// constructor
public shared this( size_t capacity ){
// initialise
numberOfItems = 0;
this.capacity = capacity;
// create mutex
listMutex = cast(shared)(new Mutex());
writeln("Cons Shared");
}
}
While class is written in this way, in main function, I wrote that code:
auto list1 = new shared FixedList!int( 128 );
auto list2 = new FixedList!int( 128 );
Output with this, there is no error at all and the output is as below:
Cons Shared
Cons Normal
What I do next is to remove both writeln lines from the code, and when I recompile the code, it starts showing error messages as below:
src/webapp.d(61): Error: constructor lists.FixedList!(int).FixedList.this called with argument types:
((int) shared)
matches both:
lists.d(28): lists.FixedList!(int).FixedList.this(ulong capacity)
and:
lists.d(37): lists.FixedList!(int).FixedList.this(ulong capacity)
src/app.d(61): Error: no constructor for FixedList
src/app.d(62): Error: constructor lists.FixedList!(int).FixedList.this called with argument types:
((int))
matches both:
lists.d(28): lists.FixedList!(int).FixedList.this(ulong capacity)
and:
lists.d(37): lists.FixedList!(int).FixedList.this(ulong capacity)
src/app.d(62): Error: no constructor for FixedList
make: *** [all] Error 1
Basically writeln function is preventing the error. Actually writeln is preventing in many places and I am not sure about why this is happening.
I even tried to compile the the code with m32 flag for 32-bit, but it is still same. Am I doing something wrong, or is this a bug?
pure, nothrow, and #safe are inferred for template functions. As FixedList is templated, its constructors are templated. writeln is not (and cannot be) pure as it does I/O. So, while writeln is in the constructors, they are inferred to not be pure, but everything else that the constructors are doing is pure, so without the calls to writeln, they become pure.
Under some circumstances, the compiler is able to alter the return type of pure functions to implicitly convert it to immutable or shared. This works, because in those cases, the compiler knows that what's being returned is a new, unique object and that casting it to immutable or shared would not violate the type system. Not all pure functions qualify, as the parameter types can affect whether the compiler can guarantee that the return value is unique, but many pure functions are able to take advantage of this and implicitly convert their return value to immutable or shared. This is useful, because it can avoid code duplication (for different return types) or copying - since if the type returned doesn't match what you need with regards to immutable or shared, and you can't guarantee that it's not referred to elsewhere, you have to copy it to get the type that you want. In this case, the compiler is able to make the guarantee that the object is not referred to elsewhere, so it can safely cast it for you.
Constructors effectively return new values, so they can be affected by this feature. This makes it so that if a constructor is pure, you can often construct immutable and shared values from it without having to duplicate the constructor (like you'd have to do if it weren't pure). As with other pure functions, whether this works or not depends on the constructor's parameter types, but it's frequently possible, and it helps avoid code duplication.
What's causing you problems is that when FixedList's constructors are both pure, the compiler is able to use either of them to construct a shared object. So, it doesn't know which one to choose, and gives you an ambiguity error.
I've reported this as a bug on the theory that the compiler should probably prefer the constructer which is explicitly marked as shared, but what the compiler devs will decide, I don't know. The ability to implicitly convert return values from pure functions is a fairly new feature and exactly when we can and can't do those implicit conversions is still being explored, which can result both in unanticipated problems (like this one probably is) as well as compiler bugs (e.g. there's at least one case with immutable, where it currently does the conversion when it shouldn't). I'm sure that these issues will be ironed out fairly quickly though.
A pure constructor can build a shared object without being marked shared itself.
Apparently, pureness is inferred for constructors.
writeln is not pure. So, with it in place, the constructors are not pure.
When writeln is removed, the constructors become pure. Both constructors now match the shared call.
Is it possible to call a function by name in Objective C? For instance, if I know the name of a function ("foo"), is there any way I can get the pointer to the function using that name and call it? I stumbled across a similar question for python here and it seems it is possible there. I want to take the name of a function as input from the user and call the function. This function does not have to take any arguments.
For Objective-C methods, you can use performSelector… or NSInvocation, e.g.
NSString *methodName = #"doSomething";
[someObj performSelector:NSSelectorFromString(methodName)];
For C functions in dynamic libraries, you can use dlsym(), e.g.
void *dlhandle = dlopen("libsomething.dylib", RTLD_LOCAL);
void (*function)(void) = dlsym(dlhandle, "doSomething");
if (function) {
function();
}
For C functions that were statically linked, not in general. If the corresponding symbol hasn’t been stripped from the binary, you can use dlsym(), e.g.
void (*function)(void) = dlsym(RTLD_SELF, "doSomething");
if (function) {
function();
}
Update: ThomasW wrote a comment pointing to a related question, with an answer by dreamlax which, in turn, contains a link to the POSIX page about dlsym. In that answer, dreamlax notes the following with regard to converting a value returned by dlsym() to a function pointer variable:
The C standard does not actually define behaviour for converting to and from function pointers. Explanations vary as to why; the most common being that not all architectures implement function pointers as simple pointers to data. On some architectures, functions may reside in an entirely different segment of memory that is unaddressable using a pointer to void.
With this in mind, the calls above to dlsym() and the desired function can be made more portable as follows:
void (*function)(void);
*(void **)(&function) = dlsym(dlhandle, "doSomething");
if (function) {
(*function)();
}