Skip to content

Instantly share code, notes, and snippets.

@PappasBrent
Last active October 27, 2022 17:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PappasBrent/d573d1ae739b1dd3ae6f669629de7ddd to your computer and use it in GitHub Desktop.
Save PappasBrent/d573d1ae739b1dd3ae6f669629de7ddd to your computer and use it in GitHub Desktop.
Examples of Macros that Fall under PRE00-C-EX5 and not PRE00-C-EX4
// The macro ADDRESS_OF reads the L-value of its argument x.
// If ADDRESS_OF were turned into a function, the L-value of
// its argument would change.
// Since it is a macro, this does not happen.
// Therefore, call-by-name semantics are required for ADDRESS_OF
// to function properly.
// This means ADDRESS_OF falls under EX5.
#define ADDRESS_OF(x) (&(x))
void foo()
{
// ADDRESS_OF is only ever invoked with an argument of type int.
// Therefore, ADDRESS_OF is not used to implement a generic function.
// This means ADDRESS_OF does not fall under EX4.
int x = 0;
int y = 0;
int z = 0;
int *a = ADDRESS_OF(x);
int *b = ADDRESS_OF(y);
int *c = ADDRESS_OF(z);
}
struct node_t
{
struct node_t *next;
};
// In this example, the macro CONNECT assigns the next member of
// the argument u to the address of the argument v
// CONNECT is not used polymorphically, so it does not fall under EX4.
// CONNECT only works correctly under call-by-name semantics, so it falls under EX5.
#define CONNECT(u, v) (((u)->next) = (&(v)))
void bar()
{
struct node_t x, y, z;
CONNECT(&x, y);
CONNECT(&y, z);
z.next = NULL;
}
#include <string.h>
#define CAP 32
struct person_t
{
char name[CAP];
};
// Assigns the name field of a person_t pointer to the given name
void person_t_set_name(struct person_t *p, char *name)
{
strncpy(p->name, name, CAP);
}
// SET_NAME is defined as an alias for person_t_set_name
// It is only ever invoked with the same types, so it does not fall under EX4.
// It does not behave the same under call-by-value semantics, so it falls under
// EX5.
#define SET_NAME(p, name) (person_t_set_name((&(p)), name))
void baz()
{
struct person_t p, q, r;
char name[CAP];
strncpy(name, "Alpha", CAP);
SET_NAME(p, name);
strncpy(name, "Beta", CAP);
SET_NAME(q, name);
strncpy(name, "Gamma", CAP);
SET_NAME(r, name);
}
@PappasBrent
Copy link
Author

Formatting on example 1.
Add example 2.

@PappasBrent
Copy link
Author

Wrap definition of CONNECT in example 2 in parentheses

@PappasBrent
Copy link
Author

Add example 3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment