BOOL MACIsTxReady(void)
{
return !ReadETHReg(ECON1).ECON1bits.TXRTS;
}
is this ReadETHReg(ECON1) a function and then what the thing that follows it is?
Excuse my bad English.
read it as this
xx = ReadETHReg(ECON1);
yy = xx.ECON1bits;
zz = !yy.TXRTS;
you need to explore the definition of ReadETHReg to find out what it returns (probably a struct)
or it might be a macro
Due to operator precedence,
return !ReadETHReg(ECON1).ECON1bits.TXRTS;
is equivalent to:
return !(ReadETHReg(ECON1).ECON1bits.TXRTS);
It would seem that ReadETHReg(ECON1) returns a struct that has a member ECON1bits, which in turn is a struct that has a member TXRTS.
This ReadETHReg(ECON1) is a function that returns a struct. This .ECON1bits.TXRTS is accessing a value inside another struct inside the first struct returned.
Like in this code:
#include <stdbool.h>
typedef bool BOOL;
int ECON1 = 42;
struct S {
struct {
bool TXRTS;
} ECON1bits;
};
struct S ReadETHReg(int val)
{
struct S ret;
ret.ECON1bits.TXRTS = val > 40 && val < 50;
return ret;
}
BOOL MACIsTxReady(void)
{
return !ReadETHReg(ECON1).ECON1bits.TXRTS;
}
Related
Im beggining with linked list in C, and I found some problems where (if I understood well) manipulate linked lists without knowing internal structre (fields)!
Is it possible to append/remove an item in a linked list without knowledge of it's internal structure(opaque) given a pointer to the linked list?
Edit (adding details).
So the problem is to create a set of functions to manipulate linked lists, given a handler on the linked list as a parameter which is declared in the follwoing way :
typedef struct list *handler;
so for example I created a function to create a linked list :
handler ListCreate()
{
handler list = (handler)malloc(sizeof(handler));
if(!list)
{
printf("can not allocate memory \n");
return NULL;
}
return list;
}
but when it comes to appending, Im just blocked and I thought it can't be done, but maybe I'm wrong.
So this is the prototype of the function :
int ListAppend(handler list, void *item)
I wanted to do something similar, but I had to figure it out myself. The idea is to make an opaque object interface, and then give access to attributes of the implementation file by casting using a switch statement. I'm doing it this way to follow the dependency inversion principle. All of the code is in a single file to show that it compiles, but the three comment lines //interface, //dependency, and //context can be broken into different files so you can try different implementations of the dependency file without having to change the interface file.
#include <stdlib.h>
#include <stdio.h>
//interface
typedef enum {
DEP1,
DEP2
} Type;
typedef struct Interface{
struct Interface* ptr;
void* data;
int (*getConcreteStuff)(struct Interface*, Type t);
} Interface;
//dependency
typedef struct {
int concreteStuff1;
} Dependency1;
typedef struct {
int concreteStuff2;
} Dependency2;
static int getConcreteStuff(Interface* interface, Type t) {
switch(t){
case DEP1:
return ((Dependency1*) interface->data)->concreteStuff1;
break;
case DEP2:
return ((Dependency2*) interface->data)->concreteStuff2;
break;
}
}
Interface Dependency1_new(Interface* ptr){
Dependency1* d = malloc(sizeof(*d));
d->concreteStuff1 = 1;
struct Interface x = {ptr, d, getConcreteStuff };
return x;
}
Interface Dependency2_new(Interface* ptr){
Dependency2* d = malloc(sizeof(*d));
d->concreteStuff2 = 2;
struct Interface y = {ptr, d, getConcreteStuff };
return y;
}
//context
typedef struct {
Interface i;
} Context;
void Context_doSomething(Context* ctx, Type t){
printf("%d\n", ctx->i.getConcreteStuff(&ctx->i, t));
}
int main(){
Context ctx1 = { Dependency1_new(NULL) };
Context_doSomething(&ctx1, DEP1);
Context ctx2 = { Dependency2_new(&ctx1.i) };
Context_doSomething(&ctx2, DEP2);
Context ctx3 = { *ctx2.i.ptr };
Context_doSomething(&ctx3, DEP1);
return 1;
}
I want to prevent invalid value enum assignment. I know if i even assign value that is not in enum it will work. Example:
enum example_enum
{
ENUM_VAL0,
ENUM_VAL1,
ENUM_VAL2,
ENUM_VAL3
};
void example_function(void)
{
enum example_enum the_enum = ENUM_VAL3; // correct
the_enum = 41; // will work
the_enum = 0xBADA55; // also will work
bar(the_enum); // this function assumes that input parameter is correct
}
Is there easy, efficient way to check if assignment to enum is correct? I could test value by function
void foo(enum example_enum the_enum)
{
if (!is_enum(the_enum))
return;
// do something with valid enum
}
I could resolve this in following way:
static int e_values[] = { ENUM_VAL0, ENUM_VAL1, ENUM_VAL2, ENUM_VAL3 };
int is_enum(int input)
{
for (int i=0;i<4;i++)
if (e_values[i] == input)
return 1;
return 0;
}
For me, my solution is inefficient, how can i write this if i have more enums and more values in enums?
As long as the enum is continuous one can do something like this:
static int e_values[] = { ENUM_VAL0, ENUM_VAL1, ENUM_VAL2, ENUM_VAL3, ENUM_VAL_COUNT };
int is_enum(int input) { return 0 <= input && input < ENUM_VAL_COUNT; }
Another alternative is to not validate the enum value beforehand, but error out once the code detects an invalid value:
switch(input) {
case ENUM_VAL0: ... break;
case ENUM_VAL1: ... break;
...
default:
assert(0 && "broken enum");
break;
}
But there is no way to enforce that the enum value doesn't go out of the range at all in C. The best you can do if you want to secure the enum against fiddling is to hide the value away in a struct and then have functions to manipulate the struct. The function and struct implementation can be hidden away from the user via a forward declaration in the .h file and the implementation in the .c file:
struct example_t {
enum example_enum value;
}
void example_set_val0(example_t* v) { v->value = ENUM_VAL0; }
There is no way of warning about assigning integers that fit into the enum.
Enumerators in C are synonyms for integer types. Assuming the type chosen for enum example_enum is int, then your code is identical to:
void example_function(void)
{
int the_enum = ENUM_VAL3; // correct
the_enum = 12345; // will work
bar(the_enum); // this function assumes that input parameter is correct
}
void foo(int the_enum)
{
if (!is_enum(the_enum))
return;
// do something with valid enum
}
You could use structures, but even that can be circumvented:
struct example_enum_struct e = { 12345 };
e.value = 23456;
Basically if you want to restrict a type to specific values, you will need to perform checks.
If anyone is interested in this topic, here I have some solution which works.
typed_enums.h
#ifndef TYPED_ENUMS_H
#define TYPED_ENUMS_H
#define TYPED_ENUM(name_) \
typedef struct { int v; } name_
#define TYPED_ENUM_VALUE(name_, value_) (name_) { value_ }
#define GET_TYPED_ENUM_VALUE(en_) (en_.v)
#define TYPED_ENUM_EQ(a_, b_) (GET_TYPED_ENUM_VALUE(a_) == GET_TYPED_ENUM_VALUE(b_))
#endif
usb_class.h
#ifndef USB_CLASS_H
#define USB_CLASS_H
#include "typed_enums.h"
TYPED_ENUM(UsbClass);
#define USB_CLASS_BILLBOARD TYPED_ENUM_VALUE(UsbClass, 0x11)
#define USB_CLASS_TYPE_C_BRIDGE TYPED_ENUM_VALUE(UsbClass, 0x12)
#define USB_CLASS_DIAGNOSTIC_DEVICE TYPED_ENUM_VALUE(UsbClass, 0xDC)
#define USB_CLASS_WIRELESS_CONTROLLER TYPED_ENUM_VALUE(UsbClass, 0xE0)
#endif
usb_class_example.c
#include "typed_enums.h"
#include "usb_class.h"
#include <stdio.h>
int main(int argc, char ** argv)
{
UsbClass usbClass = USB_CLASS_WIRELESS_CONTROLLER;
usbClass = 12345; // tadam!!!! throws error
usbClass = USB_CLASS_VIDEO;
if (TYPED_ENUM_EQ(usbClass, USB_CLASS_VIDEO)) {
printf("usbClass = USB_CLASS_VIDEO\n");
}
printf("usb class value: %02X\n", GET_TYPED_ENUM_VALUE(usbClass));
return 0;
}
Pros:
enum value assignment works like struct assignment
enum for pointers also works
enum value can't be changed
Cons:
can't be used in switch
can't be directly compared
can't directly return enum number value
Note: sorry for abusing preprocessor here
I'm trying to make a game that requires dynamically sized arrays in C but my code isn't working even though identical code works in another one of my programs.
Here are my #includes
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "SwinGame.h" //API for graphics, physics etc
#include <math.h>
Here are my typedefs for the relevant structs used:
typedef struct position_data
{
double x;
double y;
} position_data;
typedef enum enemy_type_data {CIRCLE, TRIANGLE, SQUARE} enemy_type_data;
typedef struct enemy_data
{
position_data location;
enemy_type_data type;
bitmap bmp;
double health;
double speed;
int path_to;
} enemy_data;
typedef struct enemy_data_array
{
int size;
enemy_data *data;
} enemy_data_array;
Here is the function to add an element to the array:
void add_enemy(enemy_data_array *enemies)
{
enemy_data *new_array;
enemies->size++;
new_array = (enemy_data *)realloc(enemies->data, sizeof(enemy_data) * enemies->size);
if (new_array) //if realloc fails (ie out of memory) it will return null
{
enemies->data = new_array;
// enemies->data[enemies->size - 1] = read_enemy_data();
printf("Enemy added successfully!\n");
}
else
{
printf("FAILED. Out of Memory!\n");
enemies->size--;
}
}
And here is my function call and variable declaration in the main procedure:
int main()
{
path_data my_path[41];
enemy_data_array enemies;
enemies.size = 0;
add_enemy(&enemies);
}
Why isn't this working?
You invoked undefined behavior by passing indeterminate value enemies->data in uninitialized variable having automatic storage duration. Initialize it before using add_enemy().
int main()
{
path_data my_path[41];
enemy_data_array enemies;
enemies.size = 0;
enemies.data = 0; /* add this line */
add_enemy(&enemies);
}
0 is a null pointer constant and can safely be converted to pointer NULL. Unlike NULL, 0 will work without including any headers. Of course you can use enemies.data = NULL; with proper header included.
#2501's explanation is completely correct. Another solution is to change your implementation of add_enemy() to something like this:
void add_enemy(enemy_data_array *enemies)
{
enemy_data *new_array;
// check if size was non-zero
if (enemies->size++)
{
new_array = (enemy_data *)realloc(enemies->data, sizeof(enemy_data) * enemies->size);
}
// start new allocation
else
{
new_array = (enemy_data *)alloc(sizeof(enemy_data) * enemies->size);
}
if (new_array) //if (re)alloc fails (ie out of memory) it will return null
{
enemies->data = new_array;
// enemies->data[enemies->size - 1] = read_enemy_data();
printf("Enemy added successfully!\n");
}
else
{
printf("FAILED. Out of Memory!\n");
enemies->size--;
}
}
If fails because you haven't cleared the content of "enemies". Since it is a stack variable, it will contain whatever garbage data is on the stack.
set enemies.data to NULL in the main function and try it again.
I have this call on a file called 'PlayBoard.c':
MoveSucc = putBoardSquare(theBoard, getX, getY, nextTurn);
Where 'theBoard' is a pointer to struct Board. Inside the function I am changing the board's size by referencing the pointer to ANOTHER Board struct, a bigger one. Will it change 'theBoard' on 'PlayBoard.c', where MoveSucc is invoked?
EDIT: putBoardSquare is defined in another source file
EDIT: I've added the relevant functions
Boolean putBoardSquare(BoardP theBoard, int X, int Y, char val)
{
if (val != 'X' && val != 'O')
{
reportError(BAD_VAL);
return FALSE;
}
if (X<0 || Y<0)
{
reportError(OUT_OF_BOUND);
return FALSE;
}
if (X>theBoard->height || Y>theBoard->width)
{
theBoard = expandBoard(theBoard, X,Y);
}
printf("BOARD SIZE IS %d*%d\n",theBoard->height,theBoard->width);
if (theBoard->board[X][Y] == 'X' || theBoard->board[X][Y] == 'Y' )
{
reportError(SQUARE_FULL);
return FALSE;
}
if (val != turn)
{
reportError(WRONG_TURN);
return FALSE;
}
theBoard->board[X][Y] = val;
printf("PUT %c\n",theBoard->board[X][Y]);
changeTurn(val);
return TRUE;
}
static BoardP expandBoard(ConstBoardP theBoard, int X, int Y)
{
int newWidth = theBoard->width;
int newHeight = theBoard->height;
if (X>theBoard->height)
{
newHeight = (newHeight+1) * 2;
}
if (Y>theBoard->width)
{
newWidth = (newWidth+1) * 2;
}
BoardP newBoard = createNewBoard(newWidth,newHeight);
copyBoard(theBoard,newBoard);
printf("RETUNRNING NEW BOARD OF SIZE %d*%d\n",newHeight,newWidth);
return newBoard;
}
As you can see, when the user tries to place 'X' or 'O' outside the board, it needs to be expanded which happens (I know cause I've printed new board's size in expandBoard() and in putBoardSquare()). But the pointer in 'PlayBoard.c' doesn't seem to change anyway....
My question: how can I change the pointer of a struct passed as an argument to another function? In 'PlayBoard.c' I pass one struct as an argument, and I want putBoardSquare to refrence it to another struct, which will take effect in PlayBoard.c as well.
Am I clear?
EDIT
theBoard = expandBoard(theBoard, X,Y);
This assignment only changes a local variable. You'll have to add one level of indirection, as in:
MoveSucc = putBoardSquare(&theBoard, getX, getY, nextTurn);
Boolean putBoardSquare(BoardP *theBoard, int X, int Y, char val)
{
/* ... */
*theBoard = expandBoard(theBoard, X,Y);
/* ... */
}
Your question is confusing (perhaps you should post the code you have), but the error you have is cause simply by the definition of the struct not being available in PlayBoard.c. For instance, if you only have
struct foo;
void foo(struct foo *foov) { ... }
without a definition of foo available, as in
struct foo { int a; ... }
then you won't be able to access the members of the structure (see "opaque type").
If I understand correctly and you want to change where theBoard points to, you need to define it as a pointer to pointer, not as pointer.
MoveSucc = putBoardSquare(&theBoard, getX, getY, nextTurn);
and change the parameter in putBoardSquare() to ** and when you set the pointer do it like (assuming x is a pointer):
*theBoard = x;
I define a structure in a header file like so:
typedef struct {
void *data;
} point;
I want to keep other people from accessing *data directly, so I thought I'd declare the structure in the .c file instead and use something like extern typedef struct point; in the header file. That doesn't work however.
What's the best way to achieve this?
In your (public) header file:
typedef struct point point;
In your .c file:
struct point
{
void *data;
};
Note that users of your code will no longer be able to create a point on the stack, as the compiler doesn't know how big it is. You may have to provide a point_create() function which allocates memory and returns its address to the caller.
Use C++
Since jokes seem not be allowed here is the pure C version.
As another commenter pointed out if you really want to protect your internals from users of your Api you have seen and used plenty of such Apis. This Apis are e.g. the Windows or Linux user mode Apis. There you create kernel objects to which you never shall have access to. The Apis to deal with kernel objects use a synthetic construct called handle which is not simply a pointer to your own object but instead it is an index to an array where the kernel has stored the relevant meta data for your object.
You can use the same idea for your Apis as well.
Here for example is a C-Style public Api:
// Public.h
#include <stdlib.h>
typedef enum
{
None = 0,
PointType = 1
} Types;
typedef int Handle;
Handle CreateType(Types type);
int DeleteType(Handle object);
void IncrementX(Handle point);
void PrintPoint(Handle point);
As you can see you have generic methods which create and delete your objects which are defined here in an enum. Your methods which use the object will then need to lookup the integer handle to get the meta data object where the real data is stored.
This design is not very efficient if the objects you manage are small since for every object a second object is need which stores the object type, handle value and the pointer to the real data.
But you get much stronger safety guarantees such as
Type safety
Invalid handles are easy to find
Double free is impossible since you can manage the free state in the meta object
A typical usage of your Api might look like this:
Handle h = CreateType(PointType);
IncrementX(h);
IncrementX(h);
PrintPoint(h);
DeleteType(h);
And there is the super secret implementation in private.cpp where the Handle lookup array and some helper methods exist:
// Private.C
#include "stdafx.h"
#include <stdlib.h>
#include <Windows.h> // for ZeroMemory
#include "Public.h"
typedef struct
{
LPVOID pData;
Types type;
Handle handle;
} HandleInfo;
typedef struct
{
int x;
int y;
} Point;
HandleInfo *pAllocated;
int HandleBuffer = 0xffff;
unsigned char bInit = 0;
HandleInfo *GetFreeHandle()
{
int i;
if( !bInit )
{
pAllocated = (HandleInfo *) malloc(sizeof(HandleInfo)*HandleBuffer);
bInit = 1;
ZeroMemory(pAllocated, sizeof(HandleInfo)*HandleBuffer);
}
for(i=0; i<HandleBuffer; i++)
{
HandleInfo *pInfo = (pAllocated+i);
if( 0 == pInfo->handle )
{
pInfo->handle = i+1;
return pInfo;
}
}
return NULL;
}
HandleInfo * GetHandleInfo(Handle h)
{
if( h <= 0 || h >= HandleBuffer-1)
{
return NULL;
}
return (pAllocated+h-1);
}
Handle CreateType(Types typeId)
{
HandleInfo *pInfo;
pInfo = GetFreeHandle();
if( NULL == pInfo )
{
return -1;
}
pInfo->type = typeId;
switch(typeId)
{
case PointType:
pInfo->pData = malloc(sizeof(Point));
ZeroMemory(pInfo->pData, sizeof(Point));
break;
}
return pInfo->handle;
}
int DeleteType(Handle object)
{
HandleInfo *pInfo = GetHandleInfo(object);
if( NULL == pInfo )
{
return -1;
}
if( pInfo->handle != 0 )
{
free(pInfo->pData);
pInfo->pData = NULL;
pInfo->handle = 0;
return 1;
}
else
{
return 0; // Handle was already closed
}
}
void *GetObjectOfCorrectType(Handle object, Types type)
{
HandleInfo *p = GetHandleInfo(object);
if( p == NULL )
{
return NULL;
}
if( p->type != type)
{
return NULL; // handle has wrong object type
}
return p->pData;
}
void IncrementX(Handle point)
{
Point *pPoint = (Point *) GetObjectOfCorrectType(point, PointType);
if( pPoint == NULL )
{
return;
}
pPoint->x++;
}
void PrintPoint(Handle point)
{
Point *pPoint = (Point *) GetObjectOfCorrectType(point, PointType);
if( pPoint == NULL )
{
return;
}
printf("Point has x: %d y: %d", pPoint->x, pPoint->y);
}
Yours,
Alois Kraus
This is the pointer to implementation or pimpl idiom. See http://en.wikibooks.org/wiki/C++_Programming/Idioms#Pointer_To_Implementation_.28pImpl.29 for a tutorial for C++, but the idea should work in C as well.
typedef struct {
/* private members; don't access directly */
void *data;
} point;
You can have separate public header and private header files. Some libraries have conventions for this:
Xt (X11) -> header.h and headerP.h, e.g: X11/Vendor.h vs X11/VendorP.h
Qt -> header.h vs private/header_p.h, e.g: qapplication.h vs private/qapplication_p.h
If you do not want to use the declaration method (because you want the library user to access other members of your struct, for example) it is convention to prepend private member with an underscore, like this:
typedef struct {
void * _data;
} point;
Of course people could still access _data if they would really want to (just like people can access private data in C++ by adding a #define private public before their includes) but that is their own responsibility; at least you have indicated that they shouldn't do that if they want your library to behave as it should.
I use this approach in order to let client alloc the module instance in his STACK.
struct module_private {
int data;
}
typedef uint8_t module_t [sizeof (struct module_private) ];
Client will be able to see private struct content, but not access it without doing a cast that he shouldn't.
Use the following workaround:
#include <stdio.h>
#define C_PRIVATE(T) struct T##private {
#define C_PRIVATE_END } private;
#define C_PRIV(x) ((x).private)
#define C_PRIV_REF(x) (&(x)->private)
struct T {
int a;
C_PRIVATE(T)
int x;
C_PRIVATE_END
};
int main()
{
struct T t;
struct T *tref = &t;
t.a = 1;
C_PRIV(t).x = 2;
printf("t.a = %d\nt.x = %d\n", t.a, C_PRIV(t).x);
tref->a = 3;
C_PRIV_REF(tref)->x = 4;
printf("tref->a = %d\ntref->x = %d\n", tref->a, C_PRIV_REF(tref)->x);
return 0;
}
Result is:
t.a = 1
t.x = 2
tref->a = 3
tref->x = 4