Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Go: Variadic function and too many arguments?

Here's an example of the problem I'm having:

package main

import "fmt"

func foo(a int, b ...int) {
    fmt.Println(a,b)
}

func main() {
    a := 0
    aa := 1
    b := []int{2,3,4}
    foo(a, aa, b...)
}

When I run this I get the error too many arguments in call to foo. I guess I could understand why this is happening, but what's not clear to me is how I can get around it without having to make a copy of b with an extra slot at the beginning for aa (which I'd rather not do, as this code would be running quite often and with b being somewhat long).

So my question is: Am I just doing this wrong? And if not, what would be the most efficient way to do what I'm trying to do?

(Also, I can't change the signature of foo).

like image 811
Mediocre Gopher Avatar asked Sep 22 '13 17:09

Mediocre Gopher


People also ask

How do you fix too many arguments in a function?

So to fix the error “You've entered too many arguments for this function” you need to go through the content of the cell, character-by-character, to ensure that there are no syntax errors. In other words, you need to check whether all opened brackets are closed and all commas are properly in place.

What is variadic function in Golang?

A variadic function is a function that accepts a variable number of arguments. In Golang, it is possible to pass a varying number of arguments of the same type as referenced in the function signature.

What does too many arguments to function mean?

The too many arguments to function error occur because of these arguments in a function. The number of arguments should be the same in the function call and the function declaration of a program. We get this error when the number of arguments is different in the function declaration and function call.

How can attackers exploit Variadic functions?

This limitation enables (or facilitates) two attack vectors against variadic functions. First, attackers can hijack indirect calls and thereby call variadic functions over control-flow edges that are never taken during any legitimate execution of the program.


1 Answers

In the Go runtime a variadic function is implemented as if it had an extra slice parameter at the end instead of a variadic parameter.

For example:

func Foo( a int, b ...int )
func FooImpl( a int, b []int )

c := 10
d := 20

//This call
Foo(5, c, d)

// is implemented like this
b := []int{c, d}
FooImpl(5, b)

In theory Go could handle the case where some of a variadic arguments are specified directly and the rest are expanded out of an array/slice. But, it would not be efficient.

//This call
Foo(5, c, b...)

// would be implemented like this.
v := append([]int{c},b...)
FooImpl(5, v)

You can see that Go would be creating a copy of b anyways. The ethos of Go is to be as small as possible and yet still useful. So small features like this get dropped. You may be able to argue for this syntactic sugar, as it can be implemented slightly more efficiently than straight forward approach of append.

Note that expanding a slice with ... does not create a copy of the underlying array for use as the parameter. The parameter just aliases the variable. In other words it's really efficient.

like image 186
deft_code Avatar answered Oct 04 '22 03:10

deft_code