Seg fault/error 216 when using Fillchar() - pascal

After I added Fillchar() looking for do C's memset() equivalent in pascal the program give a runtime error 216.
Here's my code (if I remove FillChar() it works fine):
function NewFoo(name : string) : ptrfoo;
var sym : ptrfoo;
begin
new(sym);
FillChar(sym, SizeOf(foo), #0);
sym^.name := name;
NewFoo := sym;
end;
foo is a record and fooptr a pointer to it defined as type fooptr = ^foo;.
How do I fix this?

Fillchar takes an untyped parameter, not a pointer. As it is you are overwriting the pointer itself (and memory well beyond it) with zeroes. You want to dereference the pointer to use it with Fillchar:
FillChar(sym^, SizeOf(foo), #0);
Untyped parameters are the parameters of the form const foo, var foo, out foo with seemingly no type attached to them. They cannot be assigned or used directly, but you can dereference them and get a pointer to them. Basically, they are syntactic sugar to be able to pass records and other variables around as if they were blobs of data without having to take a pointer to them C-style from the calling end (in reality it's a bit more complex, but that's the gist of it).

Related

GoLang: why doesn't address-of operator work without a variable declaration

In Go, suppose I have a []byte of UTF-8 that I want to return as a string.
func example() *string {
byteArray := someFunction()
text := string(byteArray)
return &text
}
I would like to eliminate the text variable, but Go doesn't support the following:
func example() *string {
byteArray := someFunction()
return &string(byteArray)
}
Is this second example syntax correct? And if so, why doesn't Go support it?
Because the spec defines is that way:
For an operand x of type T, the address operation &x generates a pointer of type *T to x. The operand must be addressable, that is, either a variable, pointer indirection, or slice indexing operation; or a field selector of an addressable struct operand; or an array indexing operation of an addressable array. As an exception to the addressability requirement, x may also be a (possibly parenthesized) composite literal.
Notice that type conversions (what you are trying to do with string(byteArray)) are not included in this list.
See Marc's answer for an official citation, but here's an intuitive reason for why Go doesn't support this.
Suppose the following code
var myString string
stringPointer := &myString
*stringPointer = "some new value"
Hopefully you know, this code will write some new value into myString. This is a basic use of pointers. Now consider the modified example (pretending that it is valid code):
var myBytes []byte
// modify myBytes...
stringPointer := &string(myString)
*stringPointer = "some new value"
The question is, where in the world (or computer) are we writing to?? Where is some new value going?
In order for the language to handle this correctly, the compiler would need some internal process to "promote" the temporary value to an invisible variable, and then take the address of that. This would be adding needless complexity to make some code slightly shorter, but create this confusing situation where we have pointers with no well defined location in the program. Instead of creating these confusing ghost-variables, the language delegates to the programmer to use their own variable as usual.

Why does setting a Char variable to nil cause compilation to fail?

In my case below I don't want c to be assigned to anything until the first character of the file is read.
I tried setting the Char variable c to nil (c := nil;) but compilation fails. I tried an empty string like below, and still doesn't work.
It works when I set it to an empty space, but it seems peculiar that I have to do that.
Is there any way to initialize a Char to a null like value as you can do in other languages?
program CSVToMarkdown;
{$mode objfpc}{$H+}{$J-}
uses
Sysutils;
var
f: File of Char;
c: Char;
begin
Assign(f, 'test.csv');
Reset(f);
c := '';
while not Eof(f) do
begin
Read(f, c);
Write(c);
end;
Close(f);
ReadLn;
end.
NIL is a value for pointers, or reference types (interfaces,class, dyn arrays) in general.
Non reference types don't have a NIL value, the type char can take values from #0 to #255, and all are valid, though sometimes when interfacing to other languages #0 is interpreted as end of string.
If you mean nullable types like in Java or .NET, there is no default support for them as they have the disadvantage of the type becoming larger than need be (iow becoming a pseudo record with added NULL boolean).
There are some generics based solutions that try to implement nullable types, but I haven't used them, and they are not part of the standard distribution.

How to get a pointer to the underlying value of an Interface{} in Go

I'm interfacing with C code in Go using cgo, and I need to call a C function with a pointer to the underlying value in an Interface{} object. The value will be any of the atomic primitive types (not including complex64/complex128), or string.
I was hoping I'd be able to do something like this to get the address of ptr as an unsafe.Pointer:
unsafe.Pointer(reflect.ValueOf(ptr).UnsafeAddr())
But this results in a panic due to the value being unaddressable.
A similar question to this is Take address of value inside an interface, but this question is different, as in this case it is known that the value will always be one of the types specified above (which will be at most 64 bits), and I only need to give this value to a C function. Note that there are multiple C functions, and the one that will be called varies based off of a different unrelated parameter.
I also tried to solve this using a type switch statement, however I found myself unable to get the address of the values even after the type assertion was done. I was able to assign the values to temporary copies, then get the address of those copies, but I'd rather avoid making these copies if possible.
interface{} has own struct:
type eface struct {
typ *rtype
val unsafe.Pointer
}
You have no access to rtype directly or by linking, on the other hand, even though you'll copy whole rtype, it may be changed (deprecated) at future.
But thing is that you can replace pointer types with unsafe.Pointer (it may be anything else with same size, but pointer is much idiomatic, because each type has own pointer):
type eface struct {
typ, val unsafe.Pointer
}
So, now we can get value contained in eface:
func some_func(arg interface{}) {
passed_value := (*eface)(unsafe.Pointer(&arg)).val
*(*byte)(passed_value) = 'b'
}
some_var := byte('a')
fmt.Println(string(some_var)) // 'a'
some_func(some_var)
fmt.Println(string(some_var)) // 'a', it didn't changed, just because it was copied
some_func(&some_var)
fmt.Println(string(some_var)) // 'b'
You also might see some more usages at my repo:
https://github.com/LaevusDexter/fast-cast
Sorry for my poor English.

When is it safe in Go to reference an object only through a `uintptr`?

The Go Programming Language says in Section 13.2 that this is code is safe and x will always
be visible to the garbage collector:
pb := (*int16)(unsafe.Pointer(
uintptr(unsafe.Pointer(&x)) + unsafe.Offsetof(x.b)))
*pb = 42
And that this code is unsafe, because x is temporarily not visible to the
garbage collector, which could move it, making pb a dangling pointer:
tmp := uintptr(unsafe.Pointer(&x)) + unsafe.Offsetof(x.b)
pb := (*int16)(unsafe.Pointer(tmp))
*pb = 42
But I can't see the difference between these two examples.
In the case described as safe, after uintptr has been called, the only
reference to the x is the uintptr value, isn't it? There's a Pointer
to it on the same line, but it was an argument to uintptr, which has run,
so nothing is referencing the arguments, and so the Pointer is not live and the uintptr is the only reference to the object.
I can't see how storing the uintptr in a local variable instead of as an
expression intermediate value makes it any more safe. Aren't local variables
like tmp removed in compiler phases anyway, becoming anonymous dataflow edges,
so that the generated code should be semantically equivalent? Or does Go have
some rules for when garbage collection can run? Such as having safepoints only
between statements? But the code in the first example has method calls so I
would presume they would always be safepoints?
Found the reference I hinted at in my comments here
A uintptr is an integer, not a reference. Converting a Pointer to a uintptr creates an integer value with no pointer semantics. Even if a uintptr holds the address of some object, the garbage collector will not update that uintptr's value if the object moves, nor will that uintptr keep the object from being reclaimed.
What this means is that this expression:
pb := (*int16)(unsafe.Pointer(
uintptr(unsafe.Pointer(&x)) + unsafe.Offsetof(x.b)))
*pb = 42
Is safe because you're creating a uintptr, which is seen as an integer, not a reference, but it's immediately assigned (unless there's a race condition somewhere else, the object that x references cannot be GC'ed) until after the assignment). The uintptr (again: integer type) is also immediately cast to a pointer, turning it into a reference so the GC will manage pb. This means that:
uintptr(unsafe.Pointer(&x)) + unsafe.Offsetof(x.b)): all safe, because x clearly is an existing reference to an object
pb is assigned an integer that is (through the cast) marked as a reference to an int16 object
However, when you write this:
tmp := uintptr(unsafe.Pointer(&x)) + unsafe.Offsetof(x.b)
pb := (*int16)(unsafe.Pointer(tmp))
There is a chance that, between assigning tmp (remember integer, not reference), the actual object in memory is moved. As it says in the docs: tmp will not be updated. Thus, when you assign pb, you could end up with an invalid pointer.
think of tmp in this case as x in the first case. Rather than being a reference to an object, it's as if you wrote
tmp := 123456 // a random integer
pb := (*int16) (unsafe.Pointer(tmp)) // not safe, obviously
For example:
var pb *int16
tmp := uintptr(unsafe.Pointer(&x)) + unsafe.Offsetof(x.b)
go func() {
time.Sleep(1 * time.Second)
pb = (*int16)(unsafe.Pointer(tmp))
}()
// original value of x could be GC'ed here, before the goroutine starts, or the time.Sleep call returns
x = TypeOfX{
b: 123,
}

Can I Use the Address of a returned value? [duplicate]

What's the cleanest way to handle a case such as this:
func a() string {
/* doesn't matter */
}
b *string = &a()
This generates the error:
cannot take the address of a()
My understanding is that Go automatically promotes a local variable to the heap if its address is taken. Here it's clear that the address of the return value is to be taken. What's an idiomatic way to handle this?
The address operator returns a pointer to something having a "home", e.g. a variable. The value of the expression in your code is "homeless". if you really need a *string, you'll have to do it in 2 steps:
tmp := a(); b := &tmp
Note that while there are completely valid use cases for *string, many times it's a mistake to use them. In Go string is a value type, but a cheap one to pass around (a pointer and an int). String's value is immutable, changing a *string changes where the "home" points to, not the string value, so in most cases *string is not needed at all.
See the relevant section of the Go language spec. & can only be used on:
Something that is addressable: variable, pointer indirection, slice indexing operation, field selector of an addressable struct, array indexing operation of an addressable array; OR
A composite literal
What you have is neither of those, so it doesn't work.
I'm not even sure what it would mean even if you could do it. Taking the address of the result of a function call? Usually, you pass a pointer of something to someone because you want them to be able to assign to the thing pointed to, and see the changes in the original variable. But the result of a function call is temporary; nobody else "sees" it unless you assign it to something first.
If the purpose of creating the pointer is to create something with a dynamic lifetime, similar to new() or taking the address of a composite literal, then you can assign the result of the function call to a variable and take the address of that.
In the end you are proposing that Go should allow you to take the address of any expression, for example:
i,j := 1,2
var p *int = &(i+j)
println(*p)
The current Go compiler prints the error: cannot take the address of i + j
In my opinion, allowing the programmer to take the address of any expression:
Doesn't seem to be very useful (that is: it seems to have very small probability of occurrence in actual Go programs).
It would complicate the compiler and the language spec.
It seems counterproductive to complicate the compiler and the spec for little gain.
I recently was tied up in knots about something similar.
First talking about strings in your example is a distraction, use a struct instead, re-writing it to something like:
func a() MyStruct {
/* doesn't matter */
}
var b *MyStruct = &a()
This won't compile because you can't take the address of a(). So do this:
func a() MyStruct {
/* doesn't matter */
}
tmpA := a()
var b *MyStruct = &tmpA
This will compile, but you've returned a MyStruct on the stack, allocated sufficient space on the heap to store a MyStruct, then copied the contents from the stack to the heap. If you want to avoid this, then write it like this:
func a2() *MyStruct {
/* doesn't matter as long as MyStruct is created on the heap (e.g. use 'new') */
}
var a *MyStruct = a2()
Copying is normally inexpensive, but those structs might be big. Even worse when you want to modify the struct and have it 'stick' you can't be copying then modifying the copies.
Anyway, it gets all the more fun when you're using a return type of interface{}. The interface{} can be the struct or a pointer to a struct. The same copying issue comes up.
You can't get the reference of the result directly when assigning to a new variable, but you have idiomatic way to do this without the use of a temporary variable (it's useless) by simply pre-declaring your "b" pointer - this is the real step you missed:
func a() string {
return "doesn't matter"
}
b := new(string) // b is a pointer to a blank string (the "zeroed" value)
*b = a() // b is now a pointer to the result of `a()`
*b is used to dereference the pointer and directly access the memory area which hold your data (on the heap, of course).
Play with the code: https://play.golang.org/p/VDhycPwRjK9
Yeah, it can be annoying when APIs require the use of *string inputs even though you’ll often want to pass literal strings to them.
For this I make a very tiny function:
// Return pointer version of string
func p(s string) *string {
return &s
}
and then instead of trying to call foo("hi") and getting the dreaded cannot use "hi" (type string) as type *string in argument to foo, I just wrap the argument in a call to to p():
foo(p("hi"))
a() doesn't point to a variable as it is on the stack. You can't point to the stack (why would you ?).
You can do that if you want
va := a()
b := &va
But what your really want to achieve is somewhat unclear.
At the time of writing this, none of the answers really explain the rationale for why this is the case.
Consider the following:
func main() {
m := map[int]int{}
val := 1
m[0] = val
v := &m[0] // won't compile, but let's assume it does
delete(m, 0)
fmt.Println(v)
}
If this code snippet actually compiled, what would v point to!? It's a dangling pointer since the underlying object has been deleted.
Given this, it seems like a reasonable restriction to disallow addressing temporaries
guess you need help from More effective Cpp ;-)
Temp obj and rvalue
“True temporary objects in C++ are invisible - they don't appear in your source code. They arise whenever a non-heap object is created but not named. Such unnamed objects usually arise in one of two situations: when implicit type conversions are applied to make function calls succeed and when functions return objects.”
And from Primer Plus
lvalue is a data object that can be referenced by address through user (named object). Non-lvalues include literal constants (aside from the quoted strings, which are represented by their addresses), expressions with multiple terms, such as (a + b).
In Go lang, string literal will be converted into StrucType object, which will be a non-addressable temp struct object. In this case, string literal cannot be referenced by address in Go.
Well, the last but not the least, one exception in go, you can take the address of the composite literal. OMG, what a mess.

Resources