We can use deftrace from tools.trace in place of defn for tracing functions. How to do something similar if the function is defined by letfn?
Related
Recently I started to work with c++. I heard about exported functions but not sure what it means.
so my questions are about:
What is exported function?
Is there any difference between normal function and exported function? if yes, what is it?
How is it related with dll?
what is exported function ?
When you program with modules (pieces of code) you need to call in some module a function which was defined in some other module. Exporting is relative to that process. In C/C++ if you want to declare a function to use it without defining it in a source file, you should use the keyword "extern". In the file where that function is defined you have nothing special to make, by defaults things at global scope are automatically exported.
Is there any difference between normal function and exported function? if yes , what it is ?
Nothing special, except that the later are visible at link time.
how it is related with dll ?
See, http://msdn.microsoft.com/en-us/library/a90k134d.aspx for DLL and function export for DLL. In such a case you must declare which function should be exported.
Suppose i have a header that should work in both C and C++.
This header contains some functions that the program must define, such as:
EXPORTED void * STD_API GetSymbol(CProject * p, char * s);
How can i ensure that these functions are actually defined somewhere? Even if the project actually compiles without, it is invalid because these functions will be looked up at runtime by another module (it is to be compiled as a module/dll/dylib/whatever).
The only thing i can think of is to use the definition somewhere, perhaps in a function call. However, that requires a function implementation in the header, which we all know will lead to multiple defintions.
In C++ you can probably get away with a hack like this:
#ifdef __cplusplus
static inline void _impcheck()
{
assert(0 && "_impcheck called.");
GetSymbol(NULL, NULL);
}
#endif
(because of how inline modifer allows multiple definitions). But how about c?
Firstly, C has static and inline too.
Second, how about...
documenting that the functions are to be implemented by the user?
checking at runtime the availability of the functions and reporting an error/throwing an exception when one can't be found? dlsym() (I assume you are using the dlopen() API, is that true?) will return a null pointer when it can't find a symbol.
If you really want a link-time failure, then you can try using the functions (call them, or assign their names to volatile function pointers if you don't want side effects to be performed prematurely, etc.)
C allows exactly the same static inline function. But the compiler will probably optimize it away because your assert gets triggered so that following code is marked unreachable.
Now I analyse some old code, which was not written by me. In headers there are many declarations like this:
SVPDSDKDLLEXPORT inline C3vec mult(C3vec src, D3DXMATRIX &m);
SVPDSDKDLLEXPORT is defined as _declspec(dllexport), if it is used in SVPDSDK; as _declspec(dllimport), if it is used in any project, which uses SVPDSDK.dll. Inlining here seems very strange for me as there is no definition in the header, it is in .cpp file, but compilation and linkage of SVPDSDK and all projects, which use respective DLL, are executed without any problems. I assume, that it is just ignored and the function is exported as though is was not inlined.
I've found this discussion:
C++ : inline functions with dllimport/dllexport?
Looked like I should have removed "inline" from all such declarations, don't mix inlining and export/import. But then I found this topic in MSDN:
http://msdn.microsoft.com/en-us/library/xa0d9ste
I don't understand some parts of it.
You can define as inline a function with the dllexport attribute. In this case, the function is always instantiated and exported, whether or not any module in the program references the function. The function is presumed to be imported by another program.
Firstly, "the function is always instantiated", what does it mean? I've found only topics about template functions instantiation in C++, no any other instantiation. Is it connected only with templates or not?
Secondly, "the function is always exported". I don't understand it at all. Is it possible, that function with declspec(_dllexport) is not exported in some cases? In what cases?
Now about import:
You can also define as inline a function declared with the dllimport attribute. In this case, the function can be expanded (subject to /Ob specifications), but never instantiated. In particular, if the address of an inline imported function is taken, the address of the function residing in the DLL is returned. This behavior is the same as taking the address of a non-inline imported function.
Again, I don't understand, what means instantiation in this case.
While writing this question and analysing topic from MSDN, I made a conclusion, that function, which is exported/imported and inlined at the same time, is inlined only in its project itself (SVPDSDK in my case) and is non-inlined in all importing projects. It's not evidently declared in MSDN topic. If I don't import it in any project, which uses it, and I have not a definition in its header file, it will be an ordinary inlined function, so I will get a linkage error. Then it seems for me that it's agreeable to mix inlining and export/import, thought it contradicts an answer in the stackoverflow discussion, mentioned above. Am I right?
And I still don't understand all this words about inlined functions instantiation.
I'm sorry, that I combined some questions in one topic, but I don't know, how to divide it in separate ones, because they are united by the same issue and the same materials. However, I would be grateful, if anyone could clarify this questions for me.
In fact, inline is a sort of hint for the optimizer. Compiler can still generate a real function with body, pushing args on the stack, etc. This will not break any logic. It would definitely do so if your "inline" function would have more than 10000 lines of code. Microsoft even has special __forceinline keyword. Guess why it was introduced.
The function is always instantiated and exported ...
The wording might be not perfect here. Instantiation means here that a body and an entry point will be generated. This has nothing to do with template instantiation. The whole paragraph means that __declspec is more important than inline.
For dllimport they basically write that dllimport prevents generation of body of this inline function in the current binary module, while the inline expansion is still possible.
What is the purpose of defining a function without statements?
I have a C++ file with a list of functions defined without statements and they are not used anywhere else in the script. Does this mean they are defined in some other file?
What is the purpose of defining a function without statements?
This phrase has no meaning. But I suspect you are referring to function declaration statements that do not also contain a definition (or implementation) of said function.
void foo(); // Declaration (may be used as long as definition is linked)
Does this mean they are defined in some other file?
And, yes, typically the definitions may be found in other translation units, that are linked together to create the final executable.
void foo() { // Defining declaration (or just "definition")
/* ... */
}
The typical C++ build process should be explained fairly thoroughly in your C++ book.
What you have are function definitions.
Probably, those are just stubs which will be implemented during course of the development.
For clearing your ambiguity between declarations and definitions:
Function declaration:
void doSomething();
Function Definition:
void doSomething()
{
}
Typically, Function declarations are in Header(.h or .hpp) files while the definitions reside in the source(.cpp) file.
The declaration of the function acts as an interface for users of the function and they include the header so that they can use the function.
Note that the function prototype and its declaration is decided & fixed during the design phase while the actual function implementation is done during the development phase.
In parallel development projects usually multiple teams would work on different features which need to exchange data(through functions) amongst themselves, Once the design phase is over the interfaces are exchanged between such teams and both teams then work in parallel to develop their own features, during this phase of development sometimes, just so as to avoid to linking errors, blank functions definitions are used as stubs in projects.
When I do:
less /usr/include/stdio.h (which is only a C library - nothing to do with C++)
I see __THROW after quite a few function declarations.
Also, comments above a few functions say that 'This function is a possible cancellation point and therefore not marked with __THROW'
What is all this for?
throw is meant to be for exception handling...but as far as I know, C doesn't provide any support for it.
Please explain.
This header is likely shared between the C and C++ compiler for that vendor. Did you look what __THROW is defined as?
I suspect something akin to:
#ifdef __cplusplus
#define __THROW throw()
#else
#define __THROW
#endif
Or for actual specifications:
#ifdef __cplusplus
#define __THROW(x) throw(x)
#else
#define __THROW(x)
#endif
As you can see, in a C build, it expands to nothing. In C++, it does what you expect. This allows vendors to reuse the same file.
Just to nitpick, this isn't entirely true: "(which is only a C library - nothing to do with C++)"
The C++ standard library includes the ability to use the C standard library. The actual header is <cxxx> where xxx is the C header name. That is, to include the C header <stdlib.h> in C++, you do <cstdlib>. So it does have to do with C++. :)
This is why you see the code you do. Duplicating the header for two different languages would be a nightmare for maintenance and cleanliness.
You can do
cpp -include stdlib.h -dM /dev/null |grep '#define __THROW '
to learn what it actually expands to.
On my system, I get:
#define __THROW __attribute__ ((__nothrow__ __LEAF))
The nothrow and leaf attributes are described at
https://gcc.gnu.org/onlinedocs/gcc-6.1.0/gcc/Common-Function-Attributes.html#Common-Function-Attributes
as follows:
leaf
leaf Calls to external functions with this attribute must return to
the current compilation unit only by return or by exception handling.
In particular, a leaf function is not allowed to invoke callback
functions passed to it from the current compilation unit, directly
call functions exported by the unit, or longjmp into the unit. Leaf
functions might still call functions from other compilation units and
thus they are not necessarily leaf in the sense that they contain no
function calls at all. The attribute is intended for library functions
to improve dataflow analysis. The compiler takes the hint that any
data not escaping the current compilation unit cannot be used or
modified by the leaf function. For example, the sin function is a leaf
function, but qsort is not.
Note that leaf functions might indirectly run a signal handler defined
in the current compilation unit that uses static variables. Similarly,
when lazy symbol resolution is in effect, leaf functions might invoke
indirect functions whose resolver function or implementation function
is defined in the current compilation unit and uses static variables.
There is no standard-compliant way to write such a signal handler,
resolver function, or implementation function, and the best that you
can do is to remove the leaf attribute or mark all such static
variables volatile. Lastly, for ELF-based systems that support symbol
interposition, care should be taken that functions defined in the
current compilation unit do not unexpectedly interpose other symbols
based on the defined standards mode and defined feature test macros;
otherwise an inadvertent callback would be added.
The attribute has no effect on functions defined within the current
compilation unit. This is to allow easy merging of multiple
compilation units into one, for example, by using the link-time
optimization. For this reason the attribute is not allowed on types to
annotate indirect calls.
nothrow
nothrow The nothrow attribute is used to inform the compiler that a
function cannot throw an exception. For example, most functions in the
standard C library can be guaranteed not to throw an exception with
the notable exceptions of qsort and bsearch that take function pointer
arguments.
What __attribute__((nothrow)) means in C is answered at gcc - what is attribute nothrow used for? . Basically, it's for cooperation with C++ code, and you can use it if the function won't ever call back to exception-throwing C++ code.
To answer your other question concerning "This function is a possible cancellation point and therefore not marked with __THROW": This deals with multi-threading. You can "cancel" a thread, but it won't actually "cancel" until it reaches a cancellation point. Some more info: http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_cancel.3.html