error: cannot convert from'func::str' to 'str*' - c

I'm getting this error but I really don't know why.
#include <stdio.h>
static struct str* func(void);
int main(void) {
return 0;
}
static struct str* func(void) {
struct str {
char arimb1 : 4;
char arimb2 : 4;
char arimb3 : 4;
char arimb4 : 4;
}s;
static struct str * ptr;
ptr = &s;
return (ptr);
}
And the error(s) are:
return value type does not match the function type [E0120]
'return': cannot convert from 'func::str *' to 'str *' [C2440]
Thank you all so much!
PS: I'm using Visual Studio (Microsoft) but I've tried also repl c and I'm getting the same error there too.

The reason for the error is that you're declaring the structure within the function. The structure declaration should be outside the function, so that the type struct str is the same in both scopes.
#include <stdio.h>
struct str {
char arimb1 : 4;
char arimb2 : 4;
char arimb3 : 4;
char arimb4 : 4;
};
static struct str* func(void);
int main(void) {
return 0;
}
static struct str* func(void) {
static struct str s;
struct str *ptr;
ptr = &s;
return (ptr);
}
Also, to avoid returning a pointer to an automatic variable, you should declare s to be static. There's no need to make ptr static.

Related

container_of() for pointers

I know what container_of() does, but I want to obtain a field that is a pointer within some struct like this:
struct A {
int *ptr;
};
void some_func(int *ptr) {
struct A *a = container_of(&ptr, struct A, ptr);
}
But it seems not working. This is compiled successfully, but looks like it produces wrong pointer:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
struct A {
int *ptr;
};
void some_func(int *ptr)
{
struct A *a = container_of(&ptr, struct A, ptr);
if (a)
pr_info("%d", *a->ptr);
else
pr_info("Ooops");
}
int __init m_init(void)
{
int ptr = 10;
struct A a = {.ptr = &ptr};
some_func(&ptr);
return 0;
}
void __exit m_exit(void)
{
}
module_init(m_init);
module_exit(m_exit);
MODULE_LICENSE("GPL");
If I do container_of(ptr, struct A, ptr); this isn't compiled:
error: static assertion failed: "pointer type mismatch in container_of()"
I guess this is because ptr is a pointer, not a usual int, so __same_type will return false, so make it a pointer.
can anybody help me to fix this?
I will not work. The reason is that ptr in m_init is a local variable, so its address &ptr is meaningless for reconstruction of an address of the other local variable a.
However, you can replace:
some_func(&ptr);
with
some_func(&a.ptr);
But will require changing some_fun to take a pointer int* member of struct A. So the argument type must be int**.
void some_func(int **ptr)
{
if (!ptr) {
pr_info("Ooops");
} else {
struct A *a = container_of(ptr, struct A, ptr);
pr_info("%d", *a->ptr);
}
}

Return Pointer from function

I am new in C and literally trying to return pointer from my function to the pointer variable and have this "[Warning] assignment makes pointer from integer without a cast" no idea why compiler defines it as an int.
Can't declare my function before main as well, it throws this "undefined reference to `free_block'".
#include <stdio.h>
#include <stdlib.h>
struct block{
int num;
};
int main(int argc, char *argv[]) {
struct block *b;
b = free_block();
struct block *free_block(){
struct block *b = NULL;
return b;
}
return 0;
}
Thank you
Yea, my fault I know not too much about c syntax and had no idea about nested functions, soz.
But what could be wrong in this case:
I am trying to make my own memory allocator without using malloc or calloc functions. In my code I have the same Warning on the line with pointer = free_space_get(size);, here I have no more nested func(), my methods defined before main(), but still have no idea do I have to declare my functions or no, coz in the answer given to me it worked fine as soon as functions were defined before the main().
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct header{
size_t size;
struct header *next;
unsigned int free;
};
void *m_alloc(size_t size){
size_t total_size;
void *block;
struct header *pointer;
if(!size)
return NULL;
pointer = free_space_get(size);
if(pointer){
pointer->free = 0;
return (void*)(pointer + 1);
}
}
struct header *get_free_space(size_t size){
struct header *b = NULL;
return b;
}
int main() {
return 0;
}
Your code can be re-written as
#include <stdio.h>
#include <stdlib.h>
struct block{
int num;
};
struct block *free_block(){
struct block *b = NULL;
return b;
}
int main(int argc, char *argv[]) {
struct block *b;
b = free_block();
if(b == NULL) // Checking whether pointer is returned
printf("\n Recieved NULL \n");
return 0;
}

Defining a program local pointer of a structure

my question deals with creating variables that are visible throughout the program file. In other words, a file-local variable.
Consider this example
#include <stdio.h>
struct foo
{
char s[] = "HELLO";
int n = 5;
};
struct foo *a;
int main()
{
puts("Dummy outputs!\n");
printf("%s\n",a->s);
printf("%d\n",a->n);
return 0;
}
Now, this code snippet won't run.
Why?
Because the structure pointed to be pointer variable a will not get allocated as the statement never executed.
Now, how do you get it allocated without changing the scope of this variable a?
#include <stdio.h>
struct foo {
char const *s;
int n;
};
/* static for file-local */
static struct foo a = { "HELLO" , 5 };
int main(void) {
printf("%s\n", a.s);
printf("%d\n", a.n);
return 0;
}
Now, how do you get it allocated without changing the scope of this variable a?
I am sure there a lot of ways to solve your problem. Here's my suggestion.
Change the definition of struct foo to contain a fixed number of characters in s.
Create a as an object instead of a pointer. Initialize it with the necessary values.
Make a a static variable so its use is limited to the file only.
Use the object a instead of the pointer a in rest of the file.
#include <stdio.h>
struct foo
{
char s[20];
int n;
};
static struct foo a = {"HELLO", 20};
int main()
{
puts("Dummy outputs!\n");
printf("%s\n",a.s);
printf("%d\n",a.n);
return 0;
}
This:
struct foo
{
char s[] = "HELLO";
int n = 5;
};
Is not valid C code. You first declare the type:
struct foo
{
char s[10];
int n;
};
Then define a variable of that type:
static struct foo a = { "HELLO", 5 };
The static keyword allows this variable to have file local scope.
You can now use it like this:
static struct foo a = { "HELLO", 5 };
void other()
{
puts("Dummy outputs!\n");
printf("%s\n",a.s);
printf("%d\n",a.n);
}
int main()
{
puts("Dummy outputs!\n");
printf("%s\n",a.s);
printf("%d\n",a.n);
other();
return 0;
}
Note that a is accessible from both functions. It will not however be viewable from functions defined in other files because it is declared as static.
As for using a pointer vs the struct directly, you can take the address of this structure at any time you need to use it in that way:
some_function(&a);
well, i need to use a pointer instead of a structure directly
Try this:
#include <stdio.h>
#include<string.h>
#include<stdlib.h>
struct foo{
char s[20];
int n;
};
int main(void){
struct foo *a;
a = malloc(sizeof(struct foo));
puts("Dummy outputs!\n");
strcpy(a->s, "HELLO");
a->n = 5;
printf("%s\n",a->s);
printf("%d\n",a->n);
free(a);
return 0;
}
Output:
Dummy outputs!
HELLO
5

Understanding OOPC, am I doing it right?

I followed Alex's book on object oriented programming using ansi c.
So far tried to model a very basic string class -
Here's the code:
main.c
#include <stdio.h>
#include <stdlib.h>
#include "class.h"
#include "mystring.h"
extern const void *String_c;
int main() {
String *my = new(String_c, "A random string");
char *text = my->str(my);
printf("String contains %s of length %d", text, my->length(my));
delete(my);
free(text);
return 0;
}
class.h
#ifndef CLASS_H_
#define CLASS_H_
#include <stddef.h>
typedef struct {
size_t size;
void* (*ctor) (void* self, va_list *app);
void (*dtor) (void* self);
} Class;
void* new(const void *class, ...);
void delete(void *object);
#endif /* CLASS_H_ */
class.c
/*
* class.c
*
* Created on: 22-Mar-2014
* Author: nilesh
*/
#include <stdarg.h>
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
#include "class.h"
void *new(const void *_class, ...) {
printf("\nCreating new\n");
const Class *class = _class;
void *p = calloc(1, class->size);
assert(p);
* (const Class **) p = class;
if(class->ctor) {
va_list ap;
va_start(ap, _class);
p = class->ctor(p, &ap);
va_end(ap);
}
return p;
}
void delete(void *object) {
printf("\nDelete\n");
const Class **class = object;
if(object && *class && (*class)->dtor)
(*class)->dtor(object);
free(object);
object = NULL;
}
mystring.h
#ifndef STRING_H_
#define STRING_H_
#include <stddef.h>
#include "class.h"
typedef struct string String;
struct _string;
struct string {
const Class *class;
struct _string *_;
int (*length) (String *self);
char* (*str) (String *self);
};
extern Class _string_class;
extern const void *String_c;
#endif /* STRING_H_ */
mystring.c
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "mystring.h"
struct _string {
char *data;
int length;
};
static int length(String *self) {
return self->_->length;
}
static char* str(String *self) {
char *ret = malloc(sizeof(char) * self->_->length);
memcpy(ret, self->_->data, sizeof(char)*self->_->length);
return ret;
}
void* ctor(void *_self, va_list *app) {
printf("\nConstructor called\n");
String *self = _self;
self->_ = malloc(sizeof(struct _string));
char *text = va_arg(*app, char *);
self->_->length = strlen(text);
self->_->data = malloc(sizeof(char) * self->_->length);
memcpy(self->_->data, text, sizeof(char) * self->_->length);
self->length = length;
self->str = str;
return self;
}
void dtor(void *_self) {
printf("\nDestructor called\n");
String *self = _self;
free(self->_);
free(self->_->data);
self->_->data = NULL;
}
Class _string_class = {sizeof(String), ctor, dtor};
const void *String_c = &_string_class;
I have one question:
Why does
Class *class = object
In delete not work, while
Class **class = object
Works?
Works in the sense, in former it doesn't call dtor, but calls length and in case of latter, the call to function is (*class)->dtor which works.
The short answer is that class is of type Class **; class->dtor would work only if class were of type Class *.
You're probably getting confused because of the double indirection, so here's a longer explanation:
Think about structures layout. Imagine you have a simple structure like so:
struct example {
int xpto;
char a[10];
}
If you call a function f() and pass it a pointer p to struct example, then f() is free to cast such a pointer to int *. Dereferencing such a pointer yields the same result as p->xpto. That is, p->xpto and *(int *) p are equivalent. This happens because structure components are layed out in increasing memory addresses. xpto is the first member, meaning it's at offset 0. In other words, for any pointer to struct example, the first sizeof(int) bytes at the address pointed to by p belong to xpto.
Your string structure was defined as:
struct string {
const Class *class;
struct _string *_;
int (*length) (String *self);
char* (*str) (String *self);
};
Which shows that at offset 0 of struct string there is a (read-only) pointer to Class. When you call delete(my) in main(), you are giving it a pointer to struct string - thus, the first sizeof(const Class *) bytes in the address pointed to by my are a pointer to a Class. Like we did in the example with struct example - where we casted p to a pointer to the first member - casting such a pointer to Class ** (first member is a Class *, so a pointer to the first member is of type Class **) gives direct access to the first field (and only the first).
Because of that, delete() casts the pointer you give it to a Class **, because by doing so, dereferencing such a pointer yields a Class *.
Why doesn't class->dtor() work? Because class is of type Class **, so, class->dtor, which is equivalent to (*class).dtor is invalid: *class is of type Class *, it's not a structure, and as such, there is no member named dtor. You must use (*class)->dtor, since that's the same as (*(*class)).dtor.

pointer to integer type modeled on pointer to typedef type

For didactic motives, i want to build a pointer to an integer, and i take a model from a pointer to a typedef (working example below in (1) ) but the example at (0) gives the mesage "error: syntax error before '=' token" at ptr =&a; and i can not understand why. I will thank the correction.The code is:
(0) //failing code
#include <stdio.h>
typedef int *ptr;
int main(){
int a;
ptr =&a; //<-----"error: syntax error before '=' token"
a =2;
printf("%d\an",a);
return 0;
}
(1) //working code
#include <stdio.h>
typedef struct sum {
int a,b,c;
} mytype;
int main(){
mytype sum_operation;
mytype *ptr;
ptr = &sum_operation;
(*ptr).a = 1;
(*ptr).b = 3;
(*ptr).c =(*ptr).b + (*ptr).a ;
printf("%d\n",(*ptr).c);
return 0;
}
This syntax:
typedef int *ptr;
Is not a pointer to a typedef. You're defining a new type named ptr which is a pointer to an integer.
This syntax:
ptr = &a;
is equivalent to:
int* = &a; // error: syntax error before '=' token
Which is incorrect as you must specify a variable name:
ptr myPointer = &a
which is equivalent to:
int* myPointer = &a;
If you want to declare a variable, you need to give it a name:
ptr b = &a;
// ^ This part.

Resources