Skip to content

Commit

Permalink
util: New macro CONST_CAST.
Browse files Browse the repository at this point in the history
Casts are sometimes necessary.  One common reason that they are necessary
is for discarding a "const" qualifier.  However, this can impede
maintenance: if the type of the expression being cast changes, then the
presence of the cast can hide a necessary change in the code that does the
cast.  Using CONST_CAST, instead of a bare cast, makes these changes
visible.

Inspired by my own work elsewhere:
http://git.savannah.gnu.org/cgit/pspp.git/tree/src/libpspp/cast.h#n80

Signed-off-by: Ben Pfaff <[email protected]>
  • Loading branch information
blp committed Aug 3, 2012
1 parent e9c0480 commit ebc56ba
Show file tree
Hide file tree
Showing 25 changed files with 69 additions and 55 deletions.
4 changes: 2 additions & 2 deletions lib/bitmap.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2009, 2010, 2011 Nicira, Inc.
* Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -26,7 +26,7 @@
static inline unsigned long *
bitmap_unit__(const unsigned long *bitmap, size_t offset)
{
return (unsigned long *) &bitmap[offset / BITMAP_ULONG_BITS];
return CONST_CAST(unsigned long *, &bitmap[offset / BITMAP_ULONG_BITS]);
}

static inline unsigned long
Expand Down
12 changes: 7 additions & 5 deletions lib/dpif-linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -595,8 +595,8 @@ dpif_linux_port_dump_next(const struct dpif *dpif OVS_UNUSED, void *state_,
return error;
}

dpif_port->name = (char *) vport.name;
dpif_port->type = (char *) netdev_vport_get_netdev_type(&vport);
dpif_port->name = CONST_CAST(char *, vport.name);
dpif_port->type = CONST_CAST(char *, netdev_vport_get_netdev_type(&vport));
dpif_port->port_no = vport.port_no;
return 0;
}
Expand Down Expand Up @@ -668,7 +668,7 @@ dpif_linux_flow_get(const struct dpif *dpif_,
dpif_linux_flow_get_stats(&reply, stats);
}
if (actionsp) {
buf->data = (void *) reply.actions;
buf->data = CONST_CAST(struct nlattr *, reply.actions);
buf->size = reply.actions_len;
*actionsp = buf;
} else {
Expand Down Expand Up @@ -1169,9 +1169,11 @@ parse_odp_packet(struct ofpbuf *buf, struct dpif_upcall *upcall,
memset(upcall, 0, sizeof *upcall);
upcall->type = type;
upcall->packet = buf;
upcall->packet->data = (void *) nl_attr_get(a[OVS_PACKET_ATTR_PACKET]);
upcall->packet->data = CONST_CAST(struct nlattr *,
nl_attr_get(a[OVS_PACKET_ATTR_PACKET]));
upcall->packet->size = nl_attr_get_size(a[OVS_PACKET_ATTR_PACKET]);
upcall->key = (void *) nl_attr_get(a[OVS_PACKET_ATTR_KEY]);
upcall->key = CONST_CAST(struct nlattr *,
nl_attr_get(a[OVS_PACKET_ATTR_KEY]));
upcall->key_len = nl_attr_get_size(a[OVS_PACKET_ATTR_KEY]);
upcall->userdata = (a[OVS_PACKET_ATTR_USERDATA]
? nl_attr_get_u64(a[OVS_PACKET_ATTR_USERDATA])
Expand Down
2 changes: 1 addition & 1 deletion lib/dynamic-string.c
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ ds_cstr(struct ds *ds)
const char *
ds_cstr_ro(const struct ds *ds)
{
return ds_cstr((struct ds *) ds);
return ds_cstr(CONST_CAST(struct ds *, ds));
}

/* Returns a null-terminated string representing the current contents of 'ds',
Expand Down
2 changes: 1 addition & 1 deletion lib/hmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ hmap_next_with_hash__(const struct hmap_node *node, size_t hash)
while (node != NULL && node->hash != hash) {
node = node->next;
}
return (struct hmap_node *) node;
return CONST_CAST(struct hmap_node *, node);
}

/* Returns the first node in 'hmap' with the given 'hash', or a null pointer if
Expand Down
6 changes: 3 additions & 3 deletions lib/json.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, 2010, 2011 Nicira, Inc.
* Copyright (c) 2009, 2010, 2011, 2012 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -296,14 +296,14 @@ struct json_array *
json_array(const struct json *json)
{
assert(json->type == JSON_ARRAY);
return (struct json_array *) &json->u.array;
return CONST_CAST(struct json_array *, &json->u.array);
}

struct shash *
json_object(const struct json *json)
{
assert(json->type == JSON_OBJECT);
return (struct shash *) json->u.object;
return CONST_CAST(struct shash *, json->u.object);
}

bool
Expand Down
6 changes: 3 additions & 3 deletions lib/list.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2009, 2010, 2011 Nicira, Inc.
* Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -136,7 +136,7 @@ list_pop_back(struct list *list)
struct list *
list_front(const struct list *list_)
{
struct list *list = (struct list *) list_;
struct list *list = CONST_CAST(struct list *, list_);

assert(!list_is_empty(list));
return list->next;
Expand All @@ -147,7 +147,7 @@ list_front(const struct list *list_)
struct list *
list_back(const struct list *list_)
{
struct list *list = (struct list *) list_;
struct list *list = CONST_CAST(struct list *, list_);

assert(!list_is_empty(list));
return list->prev;
Expand Down
4 changes: 2 additions & 2 deletions lib/netdev-linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -955,7 +955,7 @@ netdev_linux_send(struct netdev *netdev_, const void *data, size_t size)
sll.sll_family = AF_PACKET;
sll.sll_ifindex = ifindex;

iov.iov_base = (void *) data;
iov.iov_base = CONST_CAST(void *, data);
iov.iov_len = size;

msg.msg_name = &sll;
Expand Down Expand Up @@ -4106,7 +4106,7 @@ tc_query_qdisc(const struct netdev *netdev)
}

/* Instantiate it. */
load_error = ops->tc_load((struct netdev *) netdev, qdisc);
load_error = ops->tc_load(CONST_CAST(struct netdev *, netdev), qdisc);
assert((load_error == 0) == (netdev_dev->tc != NULL));
ofpbuf_delete(qdisc);

Expand Down
2 changes: 1 addition & 1 deletion lib/netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -847,7 +847,7 @@ do_update_flags(struct netdev *netdev, enum netdev_flags off,
int
netdev_get_flags(const struct netdev *netdev_, enum netdev_flags *flagsp)
{
struct netdev *netdev = (struct netdev *) netdev_;
struct netdev *netdev = CONST_CAST(struct netdev *, netdev_);
return do_update_flags(netdev, 0, 0, flagsp, false);
}

Expand Down
2 changes: 1 addition & 1 deletion lib/netlink-socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -683,7 +683,7 @@ nl_sock_transact(struct nl_sock *sock, const struct ofpbuf *request,
struct nl_transaction *transactionp;
struct nl_transaction transaction;

transaction.request = (struct ofpbuf *) request;
transaction.request = CONST_CAST(struct ofpbuf *, request);
transaction.reply = replyp ? ofpbuf_new(1024) : NULL;
transactionp = &transaction;

Expand Down
4 changes: 2 additions & 2 deletions lib/ofpbuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ ofpbuf_use_stub(struct ofpbuf *b, void *base, size_t allocated)
void
ofpbuf_use_const(struct ofpbuf *b, const void *data, size_t size)
{
ofpbuf_use__(b, (void *) data, size, OFPBUF_STACK);
ofpbuf_use__(b, CONST_CAST(void *, data), size, OFPBUF_STACK);
b->size = size;
}

Expand Down Expand Up @@ -408,7 +408,7 @@ ofpbuf_put_hex(struct ofpbuf *b, const char *s, size_t *n)
if (n) {
*n = b->size - initial_size;
}
return (char *) s;
return CONST_CAST(char *, s);
}

ofpbuf_put(b, &byte, 1);
Expand Down
5 changes: 3 additions & 2 deletions lib/ovsdb-data.c
Original file line number Diff line number Diff line change
Expand Up @@ -884,9 +884,10 @@ ovsdb_datum_default(const struct ovsdb_type *type)
d = &default_data[kt][vt];
if (!d->n) {
d->n = 1;
d->keys = (union ovsdb_atom *) ovsdb_atom_default(kt);
d->keys = CONST_CAST(union ovsdb_atom *, ovsdb_atom_default(kt));
if (vt != OVSDB_TYPE_VOID) {
d->values = (union ovsdb_atom *) ovsdb_atom_default(vt);
d->values = CONST_CAST(union ovsdb_atom *,
ovsdb_atom_default(vt));
}
}
return d;
Expand Down
6 changes: 3 additions & 3 deletions lib/ovsdb-idl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1820,7 +1820,7 @@ ovsdb_idl_txn_write(const struct ovsdb_idl_row *row_,
const struct ovsdb_idl_column *column,
struct ovsdb_datum *datum)
{
struct ovsdb_idl_row *row = (struct ovsdb_idl_row *) row_;
struct ovsdb_idl_row *row = CONST_CAST(struct ovsdb_idl_row *, row_);
const struct ovsdb_idl_table_class *class;
size_t column_idx;

Expand Down Expand Up @@ -1907,7 +1907,7 @@ void
ovsdb_idl_txn_verify(const struct ovsdb_idl_row *row_,
const struct ovsdb_idl_column *column)
{
struct ovsdb_idl_row *row = (struct ovsdb_idl_row *) row_;
struct ovsdb_idl_row *row = CONST_CAST(struct ovsdb_idl_row *, row_);
const struct ovsdb_idl_table_class *class;
size_t column_idx;

Expand Down Expand Up @@ -1946,7 +1946,7 @@ ovsdb_idl_txn_verify(const struct ovsdb_idl_row *row_,
void
ovsdb_idl_txn_delete(const struct ovsdb_idl_row *row_)
{
struct ovsdb_idl_row *row = (struct ovsdb_idl_row *) row_;
struct ovsdb_idl_row *row = CONST_CAST(struct ovsdb_idl_row *, row_);

if (ovsdb_idl_row_is_synthetic(row)) {
return;
Expand Down
6 changes: 3 additions & 3 deletions lib/shash.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, 2010, 2011 Nicira, Inc.
* Copyright (c) 2009, 2010, 2011, 2012 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -109,7 +109,7 @@ shash_add_nocopy__(struct shash *sh, char *name, const void *data, size_t hash)
{
struct shash_node *node = xmalloc(sizeof *node);
node->name = name;
node->data = (void *) data;
node->data = CONST_CAST(void *, data);
hmap_insert(&sh->map, &node->node, hash);
return node;
}
Expand Down Expand Up @@ -163,7 +163,7 @@ shash_replace(struct shash *sh, const char *name, const void *data)
return NULL;
} else {
void *old_data = node->data;
node->data = (void *) data;
node->data = CONST_CAST(void *, data);
return old_data;
}
}
Expand Down
5 changes: 3 additions & 2 deletions lib/sset.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011 Nicira, Inc.
* Copyright (c) 2011, 2012 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -18,6 +18,7 @@
#define SSET_H

#include "hmap.h"
#include "util.h"

#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -82,7 +83,7 @@ bool sset_equals(const struct sset *, const struct sset *);
#define SSET_NODE_FROM_HMAP_NODE(HMAP_NODE) \
CONTAINER_OF(HMAP_NODE, struct sset_node, hmap_node)
#define SSET_NAME_FROM_HMAP_NODE(HMAP_NODE) \
((const char *) (SSET_NODE_FROM_HMAP_NODE(HMAP_NODE)->name))
(CONST_CAST(const char *, (SSET_NODE_FROM_HMAP_NODE(HMAP_NODE)->name)))
#define SSET_NODE_FROM_NAME(NAME) CONTAINER_OF(NAME, struct sset_node, name)
#define SSET_FIRST(SSET) SSET_NAME_FROM_HMAP_NODE(hmap_first(&(SSET)->map))
#define SSET_NEXT(SSET, NAME) \
Expand Down
4 changes: 2 additions & 2 deletions lib/stp.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2009, 2010, 2011 Nicira, Inc.
* Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -151,7 +151,7 @@ stp_next_enabled_port(const struct stp *stp, const struct stp_port *port)
{
for (; port < &stp->ports[ARRAY_SIZE(stp->ports)]; port++) {
if (port->state != STP_DISABLED) {
return (struct stp_port *) port;
return CONST_CAST(struct stp_port *, port);
}
}
return NULL;
Expand Down
4 changes: 2 additions & 2 deletions lib/stream-ssl.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2009, 2010, 2011 Nicira, Inc.
* Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -902,7 +902,7 @@ do_ssl_init(void)

/* New OpenSSL changed TLSv1_method() to return a "const" pointer, so the
* cast is needed to avoid a warning with those newer versions. */
method = (SSL_METHOD *) TLSv1_method();
method = CONST_CAST(SSL_METHOD *, TLSv1_method());
if (method == NULL) {
VLOG_ERR("TLSv1_method: %s", ERR_error_string(ERR_get_error(), NULL));
return ENOPROTOOPT;
Expand Down
10 changes: 10 additions & 0 deletions lib/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,16 @@
#define BUILD_ASSERT_DECL_GCCONLY(EXPR) ((void) 0)
#endif

/* Casts 'pointer' to 'type' and issues a compiler warning if the cast changes
* anything other than an outermost "const" or "volatile" qualifier.
*
* The cast to int is present only to suppress an "expression using sizeof
* bool" warning from "sparse" (see
* http://permalink.gmane.org/gmane.comp.parsers.sparse/2967). */
#define CONST_CAST(TYPE, POINTER) \
((void) sizeof ((int) ((POINTER) == (TYPE) (POINTER))), \
(TYPE) (POINTER))

extern const char *program_name;
extern const char *subprogram_name;

Expand Down
2 changes: 1 addition & 1 deletion lib/vlog.c
Original file line number Diff line number Diff line change
Expand Up @@ -762,7 +762,7 @@ void
vlog_fatal_valist(const struct vlog_module *module_,
const char *message, va_list args)
{
struct vlog_module *module = (struct vlog_module *) module_;
struct vlog_module *module = CONST_CAST(struct vlog_module *, module_);

/* Don't log this message to the console to avoid redundancy with the
* message written by the later ovs_fatal_valist(). */
Expand Down
2 changes: 1 addition & 1 deletion ofproto/connmgr.c
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,7 @@ connmgr_free_controller_info(struct shash *info)
SHASH_FOR_EACH (node, info) {
struct ofproto_controller_info *cinfo = node->data;
while (cinfo->pairs.n) {
free((char *) cinfo->pairs.values[--cinfo->pairs.n]);
free(CONST_CAST(char *, cinfo->pairs.values[--cinfo->pairs.n]));
}
free(cinfo);
}
Expand Down
4 changes: 2 additions & 2 deletions ofproto/ofproto-dpif.c
Original file line number Diff line number Diff line change
Expand Up @@ -1964,7 +1964,7 @@ bundle_set(struct ofproto *ofproto_, void *aux,
break;

case PORT_VLAN_TRUNK:
trunks = (unsigned long *) s->trunks;
trunks = CONST_CAST(unsigned long *, s->trunks);
break;

case PORT_VLAN_NATIVE_UNTAGGED:
Expand All @@ -1981,7 +1981,7 @@ bundle_set(struct ofproto *ofproto_, void *aux,
bitmap_set1(trunks, vlan);
bitmap_set0(trunks, 0);
} else {
trunks = (unsigned long *) s->trunks;
trunks = CONST_CAST(unsigned long *, s->trunks);
}
break;

Expand Down
2 changes: 1 addition & 1 deletion ofproto/ofproto.c
Original file line number Diff line number Diff line change
Expand Up @@ -3455,7 +3455,7 @@ ofproto_compose_flow_refresh_update(const struct rule *rule,
fu.hard_timeout = rule->hard_timeout;
fu.table_id = rule->table_id;
fu.cookie = rule->flow_cookie;
fu.match = (struct cls_rule *) &rule->cr;
fu.match = CONST_CAST(struct cls_rule *, &rule->cr);
if (!(flags & NXFMF_ACTIONS)) {
fu.ofpacts = NULL;
fu.ofpacts_len = 0;
Expand Down
8 changes: 4 additions & 4 deletions ovsdb/ovsdb-server.c
Original file line number Diff line number Diff line change
Expand Up @@ -350,8 +350,8 @@ read_map_string_column(const struct ovsdb_row *row, const char *column_name,
union ovsdb_atom *atom_key = NULL, *atom_value = NULL;
size_t i;

datum = get_datum((struct ovsdb_row *) row, column_name, OVSDB_TYPE_STRING,
OVSDB_TYPE_STRING, UINT_MAX);
datum = get_datum(CONST_CAST(struct ovsdb_row *, row), column_name,
OVSDB_TYPE_STRING, OVSDB_TYPE_STRING, UINT_MAX);

if (!datum) {
return NULL;
Expand All @@ -374,8 +374,8 @@ read_column(const struct ovsdb_row *row, const char *column_name,
{
const struct ovsdb_datum *datum;

datum = get_datum((struct ovsdb_row *) row, column_name, type, OVSDB_TYPE_VOID,
1);
datum = get_datum(CONST_CAST(struct ovsdb_row *, row), column_name, type,
OVSDB_TYPE_VOID, 1);
return datum && datum->n ? datum->keys : NULL;
}

Expand Down
6 changes: 3 additions & 3 deletions ovsdb/row.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (c) 2009, 2010, 2011 Nicira, Inc.
/* Copyright (c) 2009, 2010, 2011, 2012 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -36,7 +36,7 @@ allocate_row(const struct ovsdb_table *table)
+ sizeof(struct ovsdb_datum) * n_fields
+ sizeof(struct hmap_node) * n_indexes);
struct ovsdb_row *row = xmalloc(row_size);
row->table = (struct ovsdb_table *) table;
row->table = CONST_CAST(struct ovsdb_table *, table);
row->txn_row = NULL;
list_init(&row->src_refs);
list_init(&row->dst_refs);
Expand Down Expand Up @@ -347,7 +347,7 @@ ovsdb_row_hash_destroy(struct ovsdb_row_hash *rh, bool destroy_rows)
HMAP_FOR_EACH_SAFE (node, next, hmap_node, &rh->rows) {
hmap_remove(&rh->rows, &node->hmap_node);
if (destroy_rows) {
ovsdb_row_destroy((struct ovsdb_row *) node->row);
ovsdb_row_destroy(CONST_CAST(struct ovsdb_row *, node->row));
}
free(node);
}
Expand Down
Loading

0 comments on commit ebc56ba

Please sign in to comment.