main() on the first place C - c

So I have written this code and I wanted to ask is it possible to write main in the first place before other things?
#include <stdio.h> // Standard Ein-/Ausgabefunktionen
#include <at89c51cc03.h> // CC03er-Grundregister
#define CS_LCD 0xffb8
xdata unsigned char eak_io #0xff80;
xdata unsigned char DIS_IR_W #CS_LCD+0x0;
xdata unsigned char DIS_DR_W #CS_LCD+0x1;
xdata unsigned char DIS_IR_R #CS_LCD+0x2;
xdata unsigned char DIS_DR_D #CS_LCD+0x3;
void init_schnittstelle(void)
{
SCON=0x52; // Initialisierung
TMOD |=0x20; // Timermodus 8-bit auto-reload
TH1=0xfa; // 4800 Baud
TR1=1;
}
void ms_warten(unsigned int multiplikator)
{
unsigned int i,j;
for(i=0;i<multiplikator;i++)
{
for(j=0;j<123;j++);
}
}
void dis_ready(void)
{
while ((DIS_IR_R & 0x80)!=0);
}
void init_lcd(void)
{
unsigned char i;
for (i=0; i<=2; i++)
{
DIS_IR_W=0x30;
ms_warten(10);
}
// Function Set: DL=1, N=1, F=0
dis_ready();
DIS_IR_W=0x38;
// Display ON/OFF: D=1, C=1, B=0
dis_ready();
DIS_IR_W=0x0c;
// Entry Mode Set: I/D=1, S=0
dis_ready();
DIS_IR_W=0x06;
}
void dis_clear(void)
{
dis_ready();
DIS_IR_W=0x01;
}
void dis_csr_set(unsigned char z, unsigned char s)
{
unsigned char csr_pos;
switch (z)
{
case 0 : csr_pos=s;
break;
case 1 : csr_pos=s+0x40;
break;
case 2 : csr_pos=s+0x14;
break;
case 3 : csr_pos=s+0x54;
break; }
dis_ready();
DIS_IR_W=(csr_pos | 0x80);
}
void dis_text(unsigned char csr, unsigned char z, unsigned char s, char *a)
{
unsigned char i;
if (csr==1) dis_csr_set(z,s);
i=0;
while(a[i]!=0)
{
dis_ready();
DIS_DR_W=a[i];
i++;
}
}
void main(void)
{
char aktuellerWert;
init_schnittstelle();
init_lcd();
while(1)
{
RI = 0;
while(!RI);
if(SBUF != aktuellerWert)
{
aktuellerWert = SBUF;
switch(aktuellerWert)
{
case 'O': dis_clear();
dis_text(1, 1, 2, "blabla");
dis_text(1, 2, 1, "blabla");
dis_text(1, 3, 3, "blabla");
break;
case 'G': dis_clear();
dis_text(1, 1, 2, "blabla");
dis_text(1, 2, 1, "blabla");
break;
case 'R': dis_clear();
dis_text(1, 1, 2, "blabla");
dis_text(1, 2, 1, "blabla");
break;
}
}
}
}
So I would like to write main method before #define, o that it would be more or less in the first position.
Thanks!

The compiler has to know just a few things about the functions that you use in your code before the are called. The actual implementation/definition of the function is not needed, only a declaration (a function prototype) is needed before calling. This can be done in two ways:
In a header file. Use this method if you want to use your functions in multiple C files.
Anywhere in the C source file (preferably in the beginning). These functions are limited to file scope, i.e. they are only available for use in the C source where they are declared.
A function prototype looks like this:
return_type function_name(type_t param1, type_t param2);
For example:
int sum(int a, int b);
Would declare the function sum, telling the compiler that
A function named sum exists somewhere
The function takes two integers as parameters
The function returns an integer.
At this point, the compiler has no idea how the function is implemented. However, since the compiler knows that it exists and what it looks like, it will compile your code just fine.
Here is a short example using your code:
#include <stdio.h> // Standard Ein-/Ausgabefunktionen
#include <at89c51cc03.h> // CC03er-Grundregister
// Function prototypes for functions used in main() are here, now the compiler
// is aware of them
void init_schnittstelle(void); // Note the semicolon
void init_lcd(void);
// I didn't include the prototype for the function ms_warten(), since the main()
// Doesn't use it directly. Declatring it beforehand wouldn't hurt, though.
int main()
{
// Your code here
}
#define CS_LCD 0xffb8 // This isn't used by main() either, so the compiler
// doesn't needto know about it before the
// main() fucntion.
xdata unsigned char eak_io #0xff80;
xdata unsigned char DIS_IR_W #CS_LCD+0x0;
xdata unsigned char DIS_DR_W #CS_LCD+0x1;
void init_schnittstelle(void)
{
// Your code here
}
void ms_warten(unsigned int multiplikator)
{
// Your code here
}

There is something called a function declaration. As opposed to a function definition like
int foo(int x)
{
return x + 42;
}
which tells the compiler what a function does, a function declaration tells the compiler how to invoke a function. This would be a valid function declaration for foo:
int foo(int x);
Notice the lack of braces and the trailing semicolon. Declaring a function is sufficient for the compiler to know how to call it. So if you declare all the functions invoked by main() up front, you can define the main function first. Here is an example of what the might look like:
void init_schnittstelle(void);
void ms_warten(unsigned int multiplikator);
void dis_ready(void);
void init_lcd(void);
void dis_clear(void);
void dis_csr_set(unsigned char z, unsigned char s);
void dis_text(unsigned char csr, unsigned char z, unsigned char s, char *a);
void main(void)
{
/* Code hier */
}
The customary order for the things in a program is this:
feature test macros
#include directives
#define directives
type and enumeration declarations
function declarations
variable definitions
function definitions
Notice that there is a bunch of stuff before you get to define main(), but you can still make main() the first function defined.

Related

In C language, is there any way to use callback with arbitrary / variable arguments?

I would like to send callbacks with different signatures for the same function. Somenthing like this:
#include <stdio.h>
#include <stdarg.h>
void a(int pa) {}
void b(int pb1, float pb2) {}
// exec implementation
int main() {
exec(a, 1);
exec(b, 1, 2.3);
}
I thought of using something like:
void exec(void (*func)(...), ...) {
int arg1;
float arg2;
va_list valist;
va_start(valist, size);
arg1 = va_arg(valist, int);
if (size == 1) {
(*func)(arg1);
va_end(valist);
return;
}
arg2 = va_arg(valist, float);
if (size == 2) {
(*func)(arg1, arg2);
va_end(valist);
return;
}
}
But obviously it doesn't work :(
The usual solution to making callback function interfaces flexible with respect to data provided to the function is to give the callback signature a void * parameter (possibly in addition to other parameters). Arbitrary data can be provided via such a parameter. Something like this:
void exec(void (*func)(void *), void *data) {
func(data);
}
struct s2 {
int i;
float f;
};
void func1(void *data) {
int i = *(int *)data;
// ...
}
void func2(void *data) {
struct s2 s = *(struct s2 *)data;
// ...
}
int main(void) {
int i = 42;
struct s2 s = { .i = 17, .f = 3.14 };
exec(func1, &i);
exec(func2, &s);
}
HOWEVER, It is possible to do something more like you describe, where the callback functions genuinely have different signatures, by specifying the callback type without a prototype. In that case, there are still at least these caveats:
If the callback functions themselves are defined with prototypes (as they should be) then the parameter types should not be any that are altered by the default argument promotions. So, pointers, ints, doubles, but not floats or short ints or chars (not an exhaustive list). If you wanted to support other parameter types then you would need to cast the function pointer before calling the function, as described later.
The callback functions cannot be variadic.
If the front-end is variadic, then it needs to be told at runtime, somehow, what the actual number and types of the arguments are.
Furthermore, there will need to be explicit calls to the callback functions, with correct arguments, so there can be only a fixed set of predetermined callback signatures supported.
For example, that might look something like this:
enum sig { INT, INT_DOUB };
void exec(void (*func)(/* no prototype */), enum sig cb_sig, ...);
void a(int pa) {}
void b(int pb1, double pb2) {}
int main(void) {
exec(a, INT, 1);
exec(b, INT_DOUB, 1, 2.3);
}
void exec(void (*func)(/* no prototype */), enum sig cb_sig, ...) {
va_list valist;
va_start(valist, cb_sig);
switch (cb_sig) {
case INT: {
int i = va_arg(valist, int);
func(i);
break;
}
case INT_DOUB: {
int i = va_arg(valist, int);
double d = va_arg(valist, double);
func(i, d);
break;
}
default:
assert(("Can't be reached", 0));
}
va_end(valist);
}
It is possible that that would elicit a few warnings, such as about a function declaration that does not provide a prototype, and about calling a (declared, but) unprototyped function. Since you know the signatures by the time you execute the calls, however, you could get rid of the latter kind of warning via appropriate casting. For example,
// ...
case INT: {
int i = va_arg(valist, int);
((void (*)(int))func)(i);
break;
}
// ...
You could change the callbacks to take a single va_list argument:
void a(va_list args)
{
int pa = va_arg(args,int);
}
void b(va_list args)
{
int pb1 = va_arg(args,int);
double pb2 = va_arg(args,double);
}
And have your other function pass the va_list along.
void exec(void (*func)(va_list), ...)
{
va_list valist;
va_start(valist, func);
func(valist);
va_end(valist);
}
You can use va_args to solve this.
#include <stdio.h>
#include <stdint.h>
#include <stdarg.h>
#define exec_func(func, ...) func(__VA_ARGS__)
long func(char *a, int b, long c, long d)
{
printf("a: %s, b: %d, c: %ld, d: %ld\n", a, b, c, d);
return c + d;
}
int main()
{
printf("c + d: %ld\n", exec_func(func, "test", 10, 1000, 1000));
}

Use case of function pointers in c

One of the common use cases I've come across when I read about function pointers is that they can be used to make a function more flexible, as part of the functionality of the function can be taken in as a parameter. An example for this is qsort where I can make a compare function to decide what is meant by greater and lesser (ascending, descending, is a multiple of,etc) and pass the compare funtion pointer to qsort function.
Here, the function repeat has addptr as parameter and therefore performs multiplication.
int add(int a, int b)
{
return a+b;
}
int (*addptr)(int,int);
int repeat(int a,int b,int (*funcptr)(int,int))
{
int i,ans=0;
for(i=0;i<a;i++)
{
ans=(*funcptr)(ans,b);
}
return ans;
}
int main()
{
addptr=&add;
printf("%d\n",repeat(7,5,addptr));
return 0;
}
But the same exact thing can be done without function pointers at all!
int add(int a, int b)
{
return a+b;
}
int repeat(int a,int b,int func(int,int))
{
int i,ans=0;
for(i=0;i<a;i++)
{
ans=func(ans,b);
}
return ans;
}
int main()
{
printf("%d\n",repeat(7,5,add));
return 0;
}
So why is this even one of the uses of function pointers?
What is the advantage of the first code over the second?
There is a rule C11 6.7.6.3/8 saying that if you write a function inside a parameter list, it will get adjusted to a pointer to function of that type:
A declaration of a parameter as ‘‘function returning type’’ shall be
adjusted to ‘‘pointer to function returning type’’,
This works similar to when you write an array as function parameter, it gets adjusted to a pointer to the first element.
That being said, it is not really meaningful to write a function as a parameter, it is just very confusing to the reader. Use function pointers instead.
EDIT
For maximum readability, I would personally recommend using this style:
typedef int operation_t (int, int);
int repeat (int a, int b, operation_t* operation)
{ ...
Though the most commonly used style is perhaps this one:
typedef int (*operation_t) (int, int);
int repeat (int a, int b, operation_t operation)
{ ...
I prefer the former since hiding pointers behind typedefs is a bad idea, and since that style makes function pointers consistent with regular pointers.
As noticed in comment by #user2390668, func in repeat in already a function pointer. And when you call it, add decays to a function pointer.
If your question is what is a possible use case for a variable holding a function pointer, we must try to imagine a use case where a function will not only be passed as a parameter, but will have to be stored. An example for that would be simulating polymorphism of structs in C. Here is an oversimplified example:
#include <stdio.h>
struct Base {
/* common member variables
...
*/
const char *name;
void (*display)(void *, FILE *fd);
};
struct S1 {
struct Base base;
/* other member variables */
};
void _S1_display(void *this, FILE *fd) {
struct S1 *s1 = this;
fprintf(fd, "In S1, name: %s\n", s1->base.name);
}
struct S2 {
struct Base base;
/* other member variables */
};
void _S2_display(void *this, FILE *fd) {
struct S2 *s2 = this;
fprintf(fd, "In S1, name: %s\n", s2->base.name);
}
void process(void *this, FILE *fd) {
struct Base *base = this; /* valid because base is first element of both S1 and S2 */
base->display(this, fd);
}
int main() {
struct S1 s1 = { "s1", &_S1_display };
struct S2 s2 = { "s2", &_S2_display };
process(&s1, stdout);
process(&s2, stdout);
return 0;
}
Ok, fur such a simply example, polymorphism would not be necessary, but as I said it is oversimplified...
You may use pointers to functions when you need a little more abstraction.
For example, you may want to manage a table of operators that a generic function should use:
int add(int a, int b) {
return a+b;
}
int sub(int a, int b) {
return a-b;
}
int mult(int a, int b) {
return a*b;
}
int div(int a, int b) {
return a/b;
}
void doit(int a,int b,int (*ptr[2])(int,int)) {
printf("%d\n",ptr[0](a,b));
printf("%d\n",ptr[1](a,b));
}
int main() {
int (*ptr[2])(int,int);
printf("additives (1) or multiplicatives (2) ?");
int choice;
scanf("%d",&choice);
switch(choice) {
case 1:
ptr[0] = &add;
ptr[1] = ⊂
break;
default:
ptr[0] = &mult;
ptr[1] = &div;
break;
}
doit(7,5,ptr);
return 0;
}
Of course you can also design a doit function with two pointers but sometimes a table is more convenient (think about a variable length table of function pointers for example, I know even in this case we may use a variable arguments list...).
At least, passing a function pointer in parameter is defining a function pointer variable...
Another example is also implementing in C object oriented programming, where you may implement methods as function pointers members.

C subscripted value is neither array nor pointer nor vector

Can you guys help me on function m? The idea is to printf the "tab", but i don't understand what is wrong
#include <stdio.h>
#define MAXL 50
#define MAXC 50
unsigned int linhas;
unsigned int colunas;
int segC [MAXL];
int segL [MAXC];
char tab[MAXL][MAXC];
void c (){
int l,c,temp;
scanf("%d %d",&linhas,&colunas);
for (l=0;l<linhas;l++){
scanf("%d[^'']",&temp);
segC[l]=temp;
}
for (c=0;c<colunas;c++){
scanf("%d[^'']",&temp);
segC[c]=temp;
}
for(l=0;l<=linhas;l++){
for(c=0;c<colunas;c++){
scanf("%c",&tab[l][c]);
}
}
}
char m (linhas,colunas,segC,segL,tab){
int l,c;
int tempi;
char tempc;
for(l=0;l<=linhas;l++){
for(c=0;c<colunas;c++){
printf("%c",tab[l][c]);
}
tempi=segL[l];
printf("%d\n",tempi);
}
for(c=0;c<colunas;c++){
tempi=segC[c];
printf("%d",tempi);
}
printf("\n");
}
char h (int line){
}
int main (){
c();
//m(linhas,colunas,segC,segL,tab);
}
Rewrite the function like this:
char m() {
/* ... */
}
You do not need to provide global variables as arguments to a function; in fact, the local function parameters shadow the global variables.
Finally, avoid omitting parameter and variable types; that is at the very least deprecated or even illegal as of C99 (omitted types default to int which is causing the problem here.)
Better yet, declare them as local variables in main() and pass them by pseudo-reference to both m() and c():
char m( unsigned int linhas, unsigned int colunas, int **segC, int **segL, char ***tab ) {
/* ... */
}
Pass the address of segC, segL, and tab when calling.
You're missing variable types:
char m (linhas,colunas,segC,segL,tab)

Variable declaration between function name and first curly brace

I am reading an article about code obfuscation in C, and one of the examples declares the main function as:
int main(c,v) char *v; int c;{...}
I've never saw something like this, v and c are global variables?
The full example is this:
#include <stdio.h>
#define THIS printf(
#define IS "%s\n"
#define OBFUSCATION ,v);
int main(c, v) char *v; int c; {
int a = 0; char f[32];
switch (c) {
case 0:
THIS IS OBFUSCATION
break;
case 34123:
for (a = 0; a < 13; a++) { f[a] = v[a*2+1];};
main(0,f);
break;
default:
main(34123,"#h3eglhl1o. >w%o#rtlwdl!S\0m");
break;
}
}
The article: brandonparker.net (No longer works), but can be found in web.archive.org
It's the old style function definition
void foo(a,b)
int a;
float b;
{
// body
}
is same as
void foo(int a, float b)
{
// body
}
Your case is same as int main(int c,char *v){...} But it's not correct.
The correct syntax is : int main(int c, char **v){...}
Or, int main(int c, char *v[]){...}
EDIT : Remember in main() , v should be char** not the char* as you have written.
I think it's K & R C style.
It is a pre-ANSI C syntax for function declaration. We don't use it anymore. It is the same as:
int main(int c, char *v)

Accessing members of the struct via void *

The solution consists of two parts, one is a static library that receives instances of struct from the user of the library. Library doesn't know what will be the type of structs, all it knows there will be two function pointers to it with a specific name.
Library Code
pre-compiled library has no way of knowing types of user structs, hence receiving via void*
void save(void *data) {
// library will save/cache user's object
data->registered(); // if register successful
}
void remove(void *data) {
// library will remove the object from memory
data->remove(); // if removed successful
}
User of the Library Code
struct Temp { // random order of fields
void (*custom1)();
void (*registered)();
void (*custom2)();
void (*remove)();
void (*custom3)();
}
void reg() {
printf("registered");
}
void rem() {
printf("removed");
}
void custom1() {}
void custom2() {}
void custom3() {}
var temp = malloc(struct Temp, sizeof(struct Temp));
temp->registered = reg;
temp->remove = rem;
temp->custom1 = custom1; // some custom functions
temp->custom2 = custom2;
temp->custom3 = custom3;
// calling library code
save(temp);
remove(temp);
Q. Is there a way for the Library to know how to iterate and go through member fields and see if there's a pointer to such function and call it available.
Is there a way for the Library to know how to iterate and go through member fields and see if there's a pointer to such function and call it available.
No there is not.
Your best bet is to create a structure in the library that has these members, and pass that structure instead of void*.
As #immibis said, there is no way for this to work (i.e. no way for the compiler to justify compiling such code) if the compiler does not know what the types of the data being passed to the function are.
Since you wanted to pass the objects along to the library without storing information about the type of each object in the library, you can fake polymorphism in C, by doing the following:
callback.h
#ifndef _CALLBACK_H_
#define _CALLBACK_H_
typedef struct {
void (*registered)();
void (*removed)();
} ICallback;
#endif _CALLBACK_H_
pre_comp.h
#ifndef _PRE_COMP_H_
#define _PRE_COMP_H_
#include "callback.h"
void save(ICallback* data);
void remove(ICallback* data);
#endif /* _PRE_COMP_H_ */
precomp.c
#include <stdlib.h> /* NULL */
#include "callback.h"
#include "pre_comp.h"
void save(ICallback *data) {
if (NULL != data && NULL != data->registered) {
data->registered(); // if register successful
}
}
void remove(ICallback *data) {
if (NULL != data && NULL != data->removed) {
data->removed(); // if removed successful
}
}
main.c
#include <stdio.h>
#include "pre_comp.h"
#include "callback.h"
struct Temp {
ICallback base; // has to be defined first for this to work
void (*custom1)();
void (*custom2)();
void (*custom3)();
};
// calling library code
void reg() {
puts("registered");
}
void rem() {
puts("removed");
}
int main() {
struct Temp data = {{reg, rem}};
save((ICallback*)&data);
remove((ICallback*)&data);
}
compiling
gcc pre_comp.c main.c
output
registered
removed
If the library has 0 information about the possible struct types, then you
cannot do it. The library has to get somehow the information or the offsets.
The only way I can think of is:
All register member have the same prototype
Pass the offset to the function.
I created an example of this
#include <stdio.h>
#include <stddef.h>
#include <stdint.h>
// function that does not know anything about any struct
void reg(void *data, size_t offset)
{
uintptr_t *p = (uintptr_t*) (((char*) data) + offset);
void (*reg)() = (void(*)()) *p;
reg();
}
struct A {
int c;
void (*reg)();
};
struct B {
int b;
int c;
void (*reg)();
};
void reg_a()
{
printf("reg of A\n");
}
void reg_b()
{
printf("reg of B\n");
}
int main(void)
{
struct A a;
struct B b;
a.reg = reg_a;
b.reg = reg_b;
reg(&a, offsetof(struct A, reg));
reg(&b, offsetof(struct B, reg));
return 0;
}
This prints:
$ ./c
reg of A
reg of B
I run it with valgrind and I did not get any errors nor warnings. I'm not sure if
this violates somehow strict aliasing rules or yields undefined behaviour
because of the uintptr_t* conversions, but at least it seems to work.
I think however, the more cleaner solution is to rewrite the register (btw. register
is a keyword in C, you cannot use that for a function name) function to
accept a function pointer and possible parameters, something like this:
#include <stdio.h>
#include <stdarg.h>
void reg(void (*func)(va_list), int dummy, ...)
{
if(func == NULL)
return;
va_list ap;
va_start(ap, dummy);
func(ap);
va_end(ap);
}
void reg1(int a, int b)
{
printf("reg1, a=%d, b=%d\n", a, b);
}
void vreg1(va_list ap)
{
int a = va_arg(ap, int);
int b = va_arg(ap, int);
reg1(a, b);
}
void reg2(const char *text)
{
printf("reg2, %s\n", text);
}
void vreg2(va_list ap)
{
const char *text = va_arg(ap, const char*);
reg2(text);
}
int main(void)
{
reg(vreg1, 0, 3, 4);
reg(vreg2, 0, "Hello world");
return 0;
}
This has the output:
reg1, a=3, b=4
reg2, Hello world
Note that reg has a dummy parameter. I do that because the man page of
stdarg says:
man stdarg
va_start():
[...]
Because the address of this argument may be used in the va_start() macro,
it should not be declared as a register variable, or as a
function or an array type.
You can take an approach similar to qsort and pass function pointers in addition to a void pointer to the structure.
Here is the function prototype for qsort, which is a function that can be used to sort arrays of any type:
void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *));
It takes a function pointer that performs the comparison because without it qsort wouldn't know how to compare two objects.
This can be applied to your task with a function prototype like this:
int DoFoo(void *thing, void (*register)(void *), void (*remove)(void *))
This function takes a void pointer to your struct and then two functions that it can call when it needs to register or remove that struct. Having the functions be members of the struct is not required and I generally do not recommend it. I recommend reading up on qsort because it is does something similar to what you are trying to do.

Resources