V version: V 0.1.16
OS: (Arch) Linux
What did you do?
I wrote bubblesort as followes:
fn bubblesort(arr mut []int) {
for i := 0; i < arr.len-1; i++ {
for j := 0; j < arr.len-i-1; j++ {
if arr[j] > arr[j+1] {
tmp := arr[j]
arr[j] = arr[j+1]
arr[j+1] = tmp
}
}
}
}
fn main() {
mut arr := [1, 45, 756, 4569, 56, 3, 8, 5, -10, -4]
println('Array unsorted:')
println(arr)
bubblesort(mut arr)
println('Array sorted:')
println(arr)
}
What did you expect to see?
This should compile to a binary and work as expected.
What did you see instead?
The following warnings:
.bubble_sort.c: In function ‘bubblesort’:
.bubble_sort.c:2990:29: error: incompatible type for argument 1 of ‘array__get’
2990 | if ( ( *(int*) array__get( arr , j) ) > ( *(int*) array__get( arr , j + 1) ) ) {
| ^~~
| |
| array_int * {aka struct array *}
.bubble_sort.c:369:25: note: expected ‘array’ {aka ‘struct array’} but argument is of type ‘array_int *’ {aka ‘struct array *’}
369 | void* array__get(array a, int i) {
| ~~~~~~^
.bubble_sort.c:2990:64: error: incompatible type for argument 1 of ‘array__get’
2990 | if ( ( *(int*) array__get( arr , j) ) > ( *(int*) array__get( arr , j + 1) ) ) {
| ^~~
| |
| array_int * {aka struct array *}
.bubble_sort.c:369:25: note: expected ‘array’ {aka ‘struct array’} but argument is of type ‘array_int *’ {aka ‘struct array *’}
369 | void* array__get(array a, int i) {
| ~~~~~~^
.bubble_sort.c:2992:32: error: incompatible type for argument 1 of ‘array__get’
2992 | int tmp= ( *(int*) array__get( arr , j) ) ;
| ^~~
| |
| array_int * {aka struct array *}
.bubble_sort.c:369:25: note: expected ‘array’ {aka ‘struct array’} but argument is of type ‘array_int *’ {aka ‘struct array *’}
369 | void* array__get(array a, int i) {
| ~~~~~~^
.bubble_sort.c:2994:37: error: incompatible type for argument 1 of ‘array__get’
2994 | int tmp12 = ( *(int*) array__get( arr , j + 1) );
| ^~~
| |
| array_int * {aka struct array *}
.bubble_sort.c:369:25: note: expected ‘array’ {aka ‘struct array’} but argument is of type ‘array_int *’ {aka ‘struct array *’}
369 | void* array__get(array a, int i) {
| ~~~~~~^
V panic: clang error
* The Problem *
As the errors state the first element of array__get is wrong. In case of arrays they are pointers and thus have to be dereferenced first.
Current C Code:
void bubblesort(array_int* arr) {
for (int i= 0 ; i < arr ->len - 1 ; i ++ ) {
for (int j= 0 ; j < arr ->len - i - 1 ; j ++ ) {
if ( ( *(int*) array__get( arr , j) ) > ( *(int*) array__get( arr , j + 1) ) ) {
int tmp= ( *(int*) array__get( arr , j) ) ;
int tmp12 = ( *(int*) array__get( arr , j + 1) );
array_set( arr , j , & tmp12) ;
int tmp13 = tmp;
array_set( arr , j + 1 , & tmp13) ;
};
};
};
}
Expected C Code:
void bubblesort(array_int* arr) {
for (int i= 0 ; i < arr ->len - 1 ; i ++ ) {
for (int j= 0 ; j < arr ->len - i - 1 ; j ++ ) {
if ( ( *(int*) array__get( *arr , j) ) > ( *(int*) array__get( *arr , j + 1) ) ) {
int tmp= ( *(int*) array__get( *arr , j) ) ;
int tmp12 = ( *(int*) array__get( *arr , j + 1) );
array_set( arr , j , & tmp12) ;
int tmp13 = tmp;
array_set( arr , j + 1 , & tmp13) ;
};
};
};
}
Note that in the corrected version arr is dereferenced in the array__get method.
hi @Liikt, I _think_ because currently you don't have pass built in types with mut, so the extra mut is making it a reference. (I don't think this is the correct behavior, I think this is still being worked) but no error with:
fn bubblesort(arr []int) {
for i := 0; i < arr.len-1; i++ {
for j := 0; j < arr.len-i-1; j++ {
if arr[j] > arr[j+1] {
tmp := arr[j]
arr[j] = arr[j+1]
arr[j+1] = tmp
}
}
}
}
fn main() {
mut arr := [1, 45, 756, 4569, 56, 3, 8, 5, -10, -4]
println('Array unsorted:')
println(arr)
bubblesort(arr)
println('Array sorted:')
println(arr)
}
I have same problem #1282
I'm working on a fix right now.
I was following the docs which have this example
fn multiply_by_2(arr mut []int) {
for i := 0; i < arr.len; i++ {
arr[i] *= 2
}
}
mut nums := [1, 2, 3]
multiply_by_2(mut nums)
println(nums) // ==> "[2, 4, 6]"
I guess this is the same issue
Fixed.
Most helpful comment
I'm working on a fix right now.