Here the current code for `igraph_edge`

(as in PR #1418 - https://github.com/igraph/igraph/pull/1418, the `develop`

version is equivalent but a little different on the eye):

```
int igraph_edge(const igraph_t *graph, igraph_integer_t eid,
igraph_integer_t *from, igraph_integer_t *to) {
if (igraph_is_directed(graph)) {
*from = IGRAPH_FROM(graph, eid);
*to = IGRAPH_TO(graph, eid);
} else {
*from = IGRAPH_TO(graph, eid);
*to = IGRAPH_FROM(graph, eid);
}
return IGRAPH_SUCCESS;
}
```

As you can see, igraph does a perhaps unexpected swapping in the case of undirected graphs, using `IGRAPH_FROM`

to fill the `to`

variable and vice versa.

@tamas has done some digging and it seems that **for undirected graphs only** igraph stores the larger vertex in `igraph->from`

(meaning it comes out with `IGRAPH_FROM`

), the smaller in `igraph->to`

(i.e. `IGRAPH_TO`

), so this function might be swapping them to satisfy a natural user expectation that if you ask for an edge, the smaller vertex id gets put into `from`

.

The same happens with `igraph_edges`

which returns a list of size `2 * m`

where the `to`

vertex always precedes the `from`

vertex.

I’m wondering whether we should do anything about this. In any case, this was surprising to me as I was using `igraph_edge`

and `IGRAPH_FROM/TO`

interchangeably in our internal functions and clearly they are **not**. So you might want to pay attention out there.