Why casting interface{} to cgo types is not allowed? - go

It's more of a technical question, not really an issue. Since we don't have variadic functions in cgo and there's currently no valid solution, I wonder if it'd be possible to cast interface{} to cgo types. So this would allow us to have more dynamic functions. I'm pretty sure we're not even allowed to assign types in a dynamic way to arguments in exported (//export) functions, neither the use of ellipsis is allowed. So what's the reason behind all those limits?
Thanks for answering.
import "C"
//export Foo
func Foo(arg1, arg2, arg3) {
}

C compilers are allowed, but not required, to return different types using different return mechanisms. For instance, some C compilers might return float results in the %f0 register, double results in the %f0:f1 register pair, integer results in the %d0 register, and pointer results in the %a0 register.
What this means for the person writing the Cgo interface for Go is that they must, in general, handle each kind of these C functions differently. In other words, it's not possible to write:
generic_type Cfunc(ctype1 arg1, ctype2 arg2) { ... }
We must know, at compile time, that Cfunc returns float/double/<some-integer-type>/<some-pointer-type> so that we can grab the correct register(s) and stuff its (or their) value(s) into the Cgo return-value slot, where the Cgo interface can get it and wrap it up for use in Go.
What this means for you, as a user of a Go compiler that implements Cgo wrappers to call C functions, is that you have to know the right type. There is no generalized answer; there is no way to use interface{} here. You must communicate the exact, correct type to the Cgo layer, so that the Cgo layer can use that exact, correct type information to generate the correct machine code at compile time.
If the C compiler writers had some way of flagging their code so that, e.g., at link time, the linker could pull in the right "save correct register to memory" location, that would enable the Cgo wrapper author to use the linker to automagically find the C function's type at link time. But these C compilers don't offer this ability to the linkers.
Is your particular compiler one of these? We don't know: you didn't say. But:
I'm pretty sure we're not even allowed to assign types in a dynamic way to arguments in exported (//export) functions, neither the use of ellipsis is allowed. So what's the reason behind all those limits?
That's correct, and the (slightly theoretical) example above is a reason. (I constructed this example by mixing actual techniques from 68k C compilers and SPARC C compilers, so I don't think there's any single C compiler like this. But examples like this did exist in the past, and SPARC systems still return integers in %o0, or %o0+%o1 on V8 SPARC, vs floating point in %f0 or %f0+%f1.)

Related

Will go compilers ignore unused functions

If there is a function from an external package that is not used at all in my project, will the compiler remove the function from the generated machine code?
This question could be targeted at any language compiler in general. But, I think the behaviour may vary language to language. So, I am interested in knowing what does go compilers do.
I would appreciate any help on understanding this.
The language spec does not mention this anywhere, and from a correctness point of view this is irrelevant.
But know that the current version does remove certain constructs that the compiler can prove is not used and will not change the runtime behaviour of the app.
Quoting from The Go Blog: Smaller Go 1.7 binaries:
The second change is method pruning. Until 1.6, all methods on all used types were kept, even if some of the methods were never called. This is because they might be called through an interface, or called dynamically using the reflect package. Now the compiler discards any unexported methods that do not match an interface. Similarly the linker can discard other exported methods, those that are only accessible through reflection, if the corresponding reflection features are not used anywhere in the program. That change shrinks binaries by 5–20%.
Methods are a "harder" case than functions because methods can be listed and called with reflection (unlike functions), but the Go tools do what they can even to remove unused methods too.
You can see examples and proof of removed / unlinked code in this answer:
How to remove unused code at compile time?
Also see other relevant questions:
Splitting client/server code
Call all functions with special prefix or suffix in Golang

What is the rationale of Go not having the const qualifier?

I'm a C++ senior programmer. I'm currently doing some Go programming. The only feature I really miss is the const qualifier. In go, if you want to modify an object, you pass its pointer. If you don't want to modify it, you pass it by value. But if the struct is big, you should pass it by pointer, which overrides the no-modification feature. Worse, you can pass an object by value, but if it contains a pointer, you can actually modify its contents, with terrible race condition dangers. Some language types like maps and slices have this feature. This happens in a language that's supposed to be built for concurrency. So the issue of avoiding modification is really non-existent in Go, and you should pass small objects that do not contain pointers (you must be aware that the object does not contain a pointer) by value, if they aren't gonna be modified.
With const, you can pass objects by const pointer and don't worrying about modification. Type-safety is about having a contract that allows speed and prevents type-related bugs. Another feature that does this too is the const qualifier.
The const type qualifier in C/C++ has various meanings. When applied to a variable, it means that the variable is immutable. That's a useful feature, and one that is missing from Go, but it's not the one you seem to be talking about.
You are talking about the way that const can be used as a partially enforced contract for a function. A function can give a pointer parameter the const qualifier to mean that the function won't change any values using that pointer. (Unless, of course, the function uses a cast (a const_cast in C++). Or, in C++, the pointer points to a field that is declared mutable.)
Go has a very simple type system. Many languages have a complex type system in which you enforce the correctness of your program by writing types. In many cases this means that a good deal of programming involves writing type declarations. Go takes a different approach: most of your programming involves writing code, not types. You write correct code by writing correct code, not by writing types that catch cases where you write incorrect code. If you want to catch incorrect code, you write analyzers, like go vet that look for cases that are invalid in your code. These kinds of analyzers are much much easier to write for Go than for C/C++, because the language is simpler.
There are advantages and disadvantages to this kind of approach. Go is making a clear choice here: write code, not types. It's not the right choice for everyone.
Please treat it as an expanded comment. I'm not any programming language designer, so can't go deep inside the details here, but will present my opinion as a long-term developer in C++ and short-term developer in Go.
Const is a non-trivial feature for the compiler, so one would have to make sure whether it's providing enough advantage for the user to implement it as well as won't sacrifice the simplicity of syntax. You might think it's just a const qualifier we're talking about, but looking at C++ itself, it's not so easy – there're a lot of caveats.
You say const is a contract and you shouldn't be able to modify it at any circumstances. One of your arguments against using read only interfaces is that you can cast it to original type and do whatever you want. Sure you can. The same way you can show a middle finger to the contract in C++ by using const_cast. For some reason it was added to the language and, not sure I should be proud of it, I've used it once or twice.
There's another modifier in C++ allowing you to relax the contract – mutable. Someone realised that const structures might actually need to have some fields modified, usually mutexes protecting internal variables. I guess you would need something similar in Go in order to be able to implement thread-safe structures.
When it comes simple const int x people can easily follow. But then pointers jump in and people really get consfused. const int * x, int * const x, const int * const x – these are all valid declarations of x, each with different contract. I know it's not a rocket science to choose the right one, but does your experience as a senior C++ programmer tell you people widely understand these and are always using the right one? And I haven't even mentioned things like const int * const * * * const * const x. It blows my mind.
Before I move to point 4, I would like to cite the following:
Worse, you can pass an object by value, but if it contains a pointer,
you can actually modify its contents
Now this is interesting accusation. There's the same issue in C++; worse – it exists even if you declare object as const, which means you can't solve the problem with a simple const qualifier. See the next point:
Per 3, and pointers, it's not so easy to express the very right contract and things sometimes get unexpected. This piece of code surprised a few people:
struct S {
int *x;
};
int main() {
int n = 7;
const S s = {&n}; // don't touch s, it's read only!
*s.x = 666; // wait, what? s is const! is satan involved?
}
I'm sure it's natural for you why the code above compiles. It's the pointer value you can't modify (the address it points to), not the value behind it. You must admit there're people around that would raise their eyebrow.
I don't know if it makes any point, but I've been using const in C++ all the time. Very accurate. Going mental about it. Not sure whether is has ever saved my ass, but after moving to Go I must admit I've never missed it. And having in mind all these edge cases and exceptions I can really believe creators of a minimalistic language like Go would decide to skip on this one.
Type-safety is about having a contract that allows speed and prevents
type-related bugs.
Agreed. For example, in Go, I love there're no implicit conversions between types. This is really preventing me from type-related bugs.
Another feature that does this too is the const qualifier.
Per my whole answer – I don't agree. Where a general const contract would do this for sure, a simple const qualifier is not enough. You then need a mutable one, maybe kind of a const_cast feature and still – it can leave you with misleading believes of protection, because it's hard to understand what exactly is constant.
Hopefully some language creators will design a perfect way of defining constants all over in our code and then we'll see it in Go. Or move over to the new language. But personally, I don't think C++'s way is a particularly good one.
(Alternative would be to follow functional programming paradigms, which would love to see all their "variables" immutable.)

gcc/clang: How to force ordering of items on the stack?

Consider the following code:
int a;
int b;
Is there a way to force that a precedes b on the stack?
One way to do the ordering would be to put b in a function:
void foo() {
int b;
}
...
int a;
foo();
However, that would generally work only if b isn't inlined.
Maybe there's a different way to do that? Putting an inline assembler between the two declarations may do a trick, but I am not sure.
Your initial question was about forcing a function call to not be inlined.
To improve on Jordy Baylac's answer, you might try to declare the function within the block calling it, and perhaps use a statement expr:
#define FOO_WITHOUT_INLINING(c,i) ({ \
extern int foo (char, int) __attribute__((noinline)); \
int r = foo(c,i); \
r; })
(If the type of foo is unknown, you could use typeof)
However, I still think that your question is badly formulated (and is meaningless, if one avoid reading your comments which should really go inside the question, which should have mentioned your libmill). By definition of inlining, a compiler can inline any function as it wants without changing the semantics of the program.
For example, a user of your library might legitimately compile it with -flto -O2 (both at compiling and at linking stage). I don't know what would happen then.
I believe you might redesign your code, perhaps using -fsplit-stack; are you implementing some call/cc in C? Then look inside the numerous existing implementations of it, and inside Gabriel Kerneis CPC.... See also setcontext(3) & longjmp(3)
Perhaps you might need to use somewhere the return_twice (and/or nothrow) function attribute of GCC, or some _Pragma like GCC optimize
Then you edited your question to change it completely (asking about order of variables on the call stack), still without mentioning in the question your libmill and its go macro (as you should; comments are volatile so should not contain most of the question).
But the C compiler is not even supposed to have a call stack (an hypothetical C99 conforming compiler could do whole program optimization to avoid any call stack) in the compiled program. And GCC is certainly allowed to put some variables outside of the call stack (e.g. only in registers) and it is doing that. And some implementations (IA64 probably) have two call stacks.
So your changed question is completely meaniningless: a variable might not sit on the stack (e.g. only be in a register, or even disappear completely if the compiler can prove it is useless after some other optimizations), and the compiler is allowed to optimize and use the same call stack slot for two variables (and GCC is doing such an optimization quite often). So you cannot force any order on the call stack layout.
If you need to be sure that two local variables a & b have some well defined order on the call stack, make them into a struct e.g.
struct { int _a, _b; } _locals;
#define a _locals._a
#define b _locals._b
then, be sure to put the &_locals somewhere (e.g. in a volatile global or thread-local variable). Since some versions of GCC (IIRC 4.8 or 4.7) had some optimization passes to reorder the fields of non-escaping struct-s
BTW, you might customize GCC with your MELT extension to help about that (e.g. introduce your own builtin or pragma doing part of the work).
Apparently, you are inventing some new dialect of C (à la CPC); then you should say that!
below there is a way, using gcc attributes:
char foo (char, int) __attribute__ ((noinline));
and, as i said, you can try -fno-inline-functions option, but this is for all functions in the compilation process
It is still unclear for me why you want function not to be inline-d, but here is non-pro solution I am proposing:
You can make this function in separate object something.o file.
Since you will include header only, there will be no way for the compiler to inline the function.
However linker might decide to inline it later at linking time.

Is there a way to perform compile time type-check in Ruby?

I know Ruby is dynamically and strongly typed, but AFAIK, current syntax doesn't allow checking the type of arguments at compile time due to lack of explicit type notation (or contract) for each argument.
If I want to perform compile-time type check, what (practically matured) options do I have?
Update
What I mean type-check is something like typical statically typed language. Such as C.
For example, C function denotes type of each argument and compiler checks passing-in argument is correct or not.
void func1(struct AAA aaa)
{
struct BBB bbb;
func1(bbb); // Wrong type. Compile time error.
}
As an another example, Objective-C does that by putting explicit type information.
- (id)method1:(AAA*)aaa
{
BBB* bbb = [[AAA alloc] init]; // Though we actually use correctly typed object...
[self method1:bbb]; // Compile time warning or error due to type contract mismatch.
}
I want something like that.
Update 2
Also, I mean compile-time = before running the script. I don't have better word to describe it…
There was a project for developing a type system, a type inferencer, a type checker and a syntax for type annotations for (a subset of) Ruby, called Diamondback Ruby. It was abandoned 4 years ago, you can find its source on GitHub.
But, basically, that language would no longer be Ruby. If static types are so important to you, you should probably just use a statically typed language such as Haskell, Scala, ML, Agda, Coq, ATS etc. That's what they're here for, after all.
RDL is a library for static type checking of Ruby/Rails programs. It has type annotations included for the standard library and (I think) for Rails. It lets you add types to methods/variables/etc. like so:
file.rb:
require 'rdl'
type '(Fixnum) -> Fixnum', typecheck: :now
def id(x)
"forty-two"
end
And then running file.rb will perform static type checking:
$ ruby file.rb
.../lib/rdl/typecheck.rb:32:in `error': (RDL::Typecheck::StaticTypeError)
.../file.rb:5:5: error: got type `String' where return type `Fixnum' expected
.../file.rb:5: "forty-two"
.../file.rb:5: ^~~~~~~~~~~
It seems to be pretty well documented!
While you can't check this in a static time-sense, you can use conditionals in your methods to run only after checking the object.
Here the #is_a? and #kind_of? come in handy...
def method(variable)
if variable.is_a? String
...
else
...
end
end
You would have the choice of returning specified error values or raise an exception. Hopefully this is close to what you are looking for.
You are asking for a "compile-time" type check, but in Ruby, there is no "compile" phase. Static analysis of Ruby code is almost impossible, since any method, even from the built-in classes, can be redefined at runtime. Classes can also be dynamically created and instantiated at runtime. How would you do type-checking for a class which doesn't even exist when the program starts?
Surely, your real goal is not just to "type-check your code". Your goal is to "write code that works", right? Type-checking is just a tool which can help you "write code that works". However, while type-checking is helpful, it has its limits. It can catch some simple bugs, but not most bugs, and not the most difficult bugs.
When you choose to use Ruby, you are giving up the benefits of type-checking. However, Ruby may allow you to get things done with much less code than other languages you are used to. Writing programs using less code, means that generally there are less bugs for you to fix. If you use Ruby skillfully, I believe the tradeoff is worth it.
Although you can't type-check your code in Ruby, there is great value in using assertions which check method arguments. In some cases, those assertions might check the type of an argument. More frequently, they will check other properties of the arguments. Then you need some tests which exercise the code. You will find that with a relatively small number of tests, you will catch more bugs than your C/C++ compiler can do.
It seems you want static types. There is not an effective way to do this in Ruby due to the language's dynamic nature.
A naive approach I can think of is to make a "contract" like this:
def up(name)
# name(string)
name.upcase
end
So the first line of each method will be a comment declaring what type each argument must have.
Then implement a tool that will statically scan & analyze the source and catch such errors by scanning the call sites of the above method and check the type of the passed argument whenever possible.
For example this would be easy to check:
x = "George"
up(x)
but how would you check this one:
x = rand(2).zero? "George" : 5
up(x)
In other words, most of the time the types are impossible to be deduced before runtime.
However if you do not care about the "type checking" happening statically, you could also do:
def up(name)
raise "TypeError etc." unless name.is_a? String
# ...
end
In any way, I don't think you will benefit from the above. I would recommend to make use of duck typing instead.
You might be interested in the idea of a "Pluggable type system". It means adding a static type system to a dynamic language, but the programmer decides what should be typed and what is left untyped. The typechecker stands aside the core language and it is usually implemented as a library. It can either do static checking or check types at runtime in a special "checked" mode that should be used during development and to execute tests.
The type checker for Ruby I found is called Rtc (Ruby Type Checker). Github, academic paper. The motivation is to make the requirements on a type of a parameter of a function or method explicit, move the requirements out of the tests into type annotations and turn the type annotation into an "executable documentation". Source.

Can I define C functions that accept native Go types through CGo?

For the work I'm doing to integrate with an existing library, I ended up needing to write some additional C code to provide an interface that was usable through CGo.
In order to avoid redundant data copies, I would like to be able to pass some standard Go types (e.g. Go strings) to these C adapter functions.
I can see that there are GoString and GoInterface types defined in the header CGo generates for use by exported Go functions, but is there any way to use these types in my own function prototypes that CGo will recognise?
At the moment, I've ended up using void * in the C prototypes and passing unsafe.Pointer(&value) on the Go side. This is less clean than I'd like though (for one thing, it gives the C code the ability to write to the value).
Update:
Just to be clear, I do know the difference between Go's native string type and C char *. My point is that since I will be copying the string data passed into my C function anyway, it doesn't make sense to have the code on the Go side make its own copy.
I also understand that the string layout could change in a future version of Go, and its size may differ by platform. But CGo is already exposing type definitions that match the current platform to me via the documented _cgo_export.h header it generates for me, so it seems a bit odd to talk of it being unspecified:
typedef struct { char *p; int n; } GoString;
But there doesn't seem to be a way to use this definition in prototypes visible to CGo. I'm not overly worried about binary compatibility, since the code making use of this definition would be part of my Go package, so source level compatibility would be enough (and it wouldn't be that big a deal to update the package if that wasn't the case).
Not really. You cannot safely mix, for example Go strings (string) and C "strings" (*char) code without using the provided helpers for that, ie. GoString and CString. The reason is that to conform to the language specs a full copy of the string's content between the Go and C worlds must be made. Not only that, the garbage collector must know what to consider (Go strings) and what to ignore (C strings). And there are even more things to do about this, but let me keep it simple here.
Similar and/or other restrictions/problems apply to other Go "magical" types, like map or interface{} types. In the interface types case (but not only it), it's important to realize that the inner implementation of an interface{} (again not only this type), is not specified and is implementation specific.
That's not only about the possible differences between, say gc and gccgo. It also means that your code will break at any time the compiler developers decide to change some detail of the (unspecified and thus non guaranteed) implementation.
Additionally, even though Go doesn't (now) use a compacting garbage collector, it may change and without some pinning mechanism, any code accessing Go run time stuff directly will be again doomed.
Conclusion: Pass only simple entities as arguments to C functions. POD structs with simple fields are safe as well (pointer fields generally not). From the complex Go types, use the provided helpers for Go strings, they exists for a (very good) reason.
Passing a Go string to C is harder than it should be. There is no really good way to do it today. See https://golang.org/issue/6907.
The best approach I know of today is
// typedef struct { const char *p; ptrdiff_t n; } gostring;
// extern CFunc(gostring s);
import "C"
func GoFunc(s string) {
C.CFunc(*(*C.gostring)(unsafe.Pointer(&s)))
}
This of course assumes that Go representation of a string value will not change, which is not guaranteed.

Resources