error: expected indentifier or '(' before '=' token - struct

Here's my code
#include <linux/list.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/printk.h>
#include <linux/slab.h>
typedef struct list_head list;
typedef struct student *ptr;
typedef struct student *studentDemo;
static LIST_HEAD(student_list);
struct student{
int studentNumber;
int courseCredit;
float grade;
studentDemo = kmalloc(sizeof(*studentDemp), GFP_KERNEL);
studentDemo -> studentNumber = 760120495;
studentDemo -> courseCredit = 3;
studentDemo -> grade = 3.0;
INIT_LIST_HEAD(&studentDemo->list);
}
I keep getting these errors

You have few problems:
typedef declaration is not creating a memory, therefore you can't assign something to a "typedef" string. typedef struct student * studentDemo - can be read "whenever the compiler will encoutner the string "studentDemo", replace with a pointer to a struct of type student". Obviously you can't assign anything to such a definition.
You can't assign memory to a pointer during the definition of the class/struct - this should be done during main where memory can be allocated from the stack.
You should first declare a member of type studentDemo (actually the pointer to the student struct) and then you can assign to it.
You should assign the memory during main().
Here is an example of C
#include <stdio.h>
#include <stdlib.h>
typedef struct student *studentDemo;
struct student
{
studentDemo myStruct;
};
void main()
{
struct student my_variable;
my_variable.myStruct = (studentDemo)malloc(1 * sizeof(studentDemo));
return;
}

Here:
typedef struct student *studentDemo;
you defined studentDemo as an alias-name for type (struct student *)
and here:
XXXX -> studentNumber
XXXX should be a pointer expression (posibly a variable of type struct student *), but not the type itself.

Related

Auto-interpreting a c-style string as a std::string via Boost's Property tree's .get function

I use boosts property tree, included via
#include "boost\property_tree\ptree.hpp"
And... I'd like to create a simple function which substitutes a value in case none is found via a fairly straight-forward template function:
template <typename Type>
Type getValueOrDefault( std::string const& str, Type defaultValue )
{
Type returnValue = defaultValue;
try {
returnValue = mSettings.get<Type>( str );
}
catch ( boost::property_tree::ptree_error &e )
{
// Log error!
}
return returnValue;
}
This works well in principle, but runs into a bit problems if I rely on C-style string. For example, calling the function as follows:
getValueOrDefault( "pathToImportantStuffParameter", "c:/defaultdir/" )
will result in the following error:
boost\property_tree\stream_translator.hpp(36): error C2678: binary '>>' : no operator found which takes a left-hand operand of type 'std::basic_istream<char,std::char_traits<char>>' (or there is no acceptable conversion)
The error stems from passing char const * as a template parameter which makes a fair bit of sense. Two obvious solutions to this issue would be to force the default value to be a std::string object, like so:
getValueOrDefault<std::string>( "pathToImportantStuffParameter", "c:/defaultdir/" )
getValueOrDefault( "pathToImportantStuffParameter", std::string("c:/defaultdir/") )
But I'm wondering if someone might know of some template magic I could sprinkle to automatically interpret c-style strings as std::strings?
You can provide a char array overload which converts the char array to a std::string and then calls the default implementation:
#include <iostream>
#include <string>
template <typename T>
T getValueOrDefault(const std::string& str, T&& defaultValue)
{
std::cout << "inside default implementation" << std::endl;
/* ... */
return defaultValue;
}
template <std::size_t N>
std::string getValueOrDefault(const std::string& str, const char (&defaultValue)[N])
{
std::cout << "inside char[] overload" << std::endl;
return getValueOrDefault(str, std::string(defaultValue));
}
int main()
{
auto x = getValueOrDefault("foo", "bar");
return 0;
}
live example
An alternative solution is to use custom type traits:
#include <string>
#include <type_traits>
template <typename T>
struct return_type
{
using type = T;
};
template <>
struct return_type<const char*>
{
using type = std::string;
};
template <typename T>
using return_type_t = typename return_type<typename std::decay<T>::type>::type;
template <typename T>
return_type_t<T> getValueOrDefault(const std::string& str, T&& defaultValue)
{
return_type_t<T> value(defaultValue);
/* ... */
return value;
}
int main()
{
auto x = getValueOrDefault("foo", "bar");
static_assert(std::is_same<decltype(x), std::string>::value, "");
return 0;
}
live example
The only way I found is to specialize getValueOrDefault for const char*, which calls getValueOrDefault with std::string explicitly:
//Note that the return value is unspecified, it returns a 'const char*' to a temporary,
//which will be destroyed when the function returns
template <>
const char* getValueOrDefault(std::string const& str, const char* defaultValue)
{
return getValueOrDefault<std::string>(str, defaultValue).c_str();
}
If you want to that function to return a std::string instead of an invalid const char*, you have to change the template signature a bit:
//Default return type is the same as paramter
template <typename Type, typename Return = Type>
Return getValueOrDefault(std::string const& str, Type defaultValue)
{
//...
}
//Trick the compiler to select this overload for 'const char*'
template <typename Return = std::string>
Return getValueOrDefault(std::string const& str, const char* defaultValue)
{
return getValueOrDefault<std::string, std::string>(str, defaultValue);
}
or you could just plain overload the function (thanks #m.s.)
//Overload for 'const char*'
std::string getValueOrDefault(std::string const& str, const char* defaultValue)
{
return getValueOrDefault<std::string>(str, defaultValue);
}
There is also a third way (if you can use C++14), using the string literal ""s:
//"c:/defaultdir/"s is a std::string (note the s after it => string literal)
getValueOrDefault("pathToImportantStuffParameter", "c:/defaultdir/"s);

How to publish a constant string in the Rust FFI?

I want to have a Rust library expose a const char * static string to C, to be compatible with an existing interface (specifically librsync). That is, the C header file has
extern char const *my_string;
In C, the library would simply have
char const *my_string = "hi";
In Rust I've tried something like
pub static my_string: *const libc::c_char = unsafe { "hi\0" as *const libc::c_char };
but this complains
error: casting `&'static str` as `*const i8` is invalid
It seems like I can't use CString etc because they won't be a compile-time constant expression.
We need a public, static, unmangled pointer to some zero-terminated bytes:
#[export_name = "CONST_C_STR"] // or #[no_mangle]
pub static CONST_C_STR: &[u8; 20] = b"a constant c string\0";
This worked with a simple C program:
#include <stdio.h>
extern char * CONST_C_STR;
int main(int argc, char *argv[]) {
printf("%s\n", CONST_C_STR);
}
The crate c_str_macro provides a convenience macro c_str!, which appends a 0 byte to a Rust string literal and presents it as a CStr reference.
Disclaimer: I'm the author of the crate.

Use structure member within s a structure using typedef

When I compile the following I get use of undeclared identifier 'rsdtHeader'
How can I do the following operation using typedef?
typedef struct
{
int length;
int x;
int y;
} SdtHeader_s;
typedef struct
{
SdtHeader_s rsdtHeader;
SdtHeader_s* rsdtEntry[(rsdtHeader.length - sizeof(rsdtHeader))/4];
} Rsdt_s;

SIGABRT error after malloc of a struct

I cant seem to solve this error i have in the malloc line of code. The error is "SIGABRT". Please teach me how to solve this problem. Thank you.
typedef struct caminho{
int nCient;
struct caminho *next;
}Caminho;
Caminho *temp1 = (Caminho*) malloc(sizeof(Caminho));
Update:
typedef struct caminho{
int nCient;
struct caminho *next;
}Caminho;
Caminho *temp1 = malloc(sizeof(Caminho));
the only other structure in the program and the only other malloc:
typedef struct Cientista{
int nCient;
int nSignal;
int profundidade;
int distancia;
struct caminho *next;
} cientista;
cientista* vectorCientistas;
scanf("%d %d", &maxCientista, &maxCaminhos);
vectorCientistas = malloc(sizeof(cientista*) * maxCientista);
PROBLEM FOUND!!
had:
vectorCientistas = malloc(sizeof(cientista*) * maxCientista);
solution:
vectorCientistas = malloc(sizeof(cientista) * maxCientista;
Was allocating memory for a pointer and i wanted a struct.

What is the point of magic value?

what is the 'magic' value in tty_driver struct
struct tty_driver {
int magic; /* magic number for this structure */
struct kref kref; /* Reference management */
struct cdev cdev;
struct module *owner;
const char *driver_name;
....
....
/* tty driver magic number */
#define TTY_DRIVER_MAGIC 0x5402
From tty_driver.h listing here.

Resources