diff --git a/src/ring.cc b/src/ring.cc
index d23f191..e090610 100644
--- a/src/ring.cc
+++ b/src/ring.cc
@@ -72,7 +72,7 @@ _vte_ring_init (VteRing *ring, gulong max_rows, gboolean has_streams)
 	}
 
 	ring->last_attr_text_start_offset = 0;
-	ring->last_attr.i = basic_cell.i.attr;
+	ring->last_attr = basic_cell.attr;
 	ring->utf8_buffer = g_string_sized_new (128);
 
 	_vte_row_data_init (&ring->cached_row);
@@ -149,7 +149,7 @@ _vte_ring_freeze_row (VteRing *ring, gulong position, const VteRowData *row)
 
 	g_string_set_size (buffer, 0);
 	for (i = 0, cell = row->cells; i < row->len; i++, cell++) {
-		VteIntCellAttr attr;
+		VteCellAttr attr;
 		int num_chars;
 
 		/* Attr storage:
@@ -163,11 +163,11 @@ _vte_ring_freeze_row (VteRing *ring, gulong position, const VteRowData *row)
 		 * That's enough to reconstruct the attrs, and to store
 		 * the text in real UTF-8.
 		 */
-		attr.s = cell->attr;
-		if (G_LIKELY (!attr.s.fragment)) {
+		attr = cell->attr;
+		if (G_LIKELY (!attr.fragment)) {
 			VteCellAttrChange attr_change;
 
-			if (ring->last_attr.i != attr.i) {
+			if (memcmp(&ring->last_attr, &attr, sizeof (VteCellAttr)) != 0) {
 				ring->last_attr_text_start_offset = record.text_start_offset + buffer->len;
 				memset(&attr_change, 0, sizeof (attr_change));
 				attr_change.text_end_offset = ring->last_attr_text_start_offset;
@@ -181,7 +181,7 @@ _vte_ring_freeze_row (VteRing *ring, gulong position, const VteRowData *row)
 
 			num_chars = _vte_unistr_strlen (cell->c);
 			if (num_chars > 1) {
-				attr.s.columns = 0;
+				attr.columns = 0;
 				ring->last_attr_text_start_offset = record.text_start_offset + buffer->len
 								  + g_unichar_to_utf8 (_vte_unistr_get_base (cell->c), NULL);
 				memset(&attr_change, 0, sizeof (attr_change));
@@ -207,7 +207,7 @@ static void
 _vte_ring_thaw_row (VteRing *ring, gulong position, VteRowData *row, gboolean do_truncate)
 {
 	VteRowRecord records[2], record;
-	VteIntCellAttr attr;
+	VteCellAttr attr;
 	VteCellAttrChange attr_change;
 	VteCell cell;
 	const char *p, *q, *end;
@@ -255,7 +255,7 @@ _vte_ring_thaw_row (VteRing *ring, gulong position, VteRowData *row, gboolean do
 			attr = attr_change.attr;
 		}
 
-		cell.attr = attr.s;
+		cell.attr = attr;
 		cell.c = g_utf8_get_char (p);
 
 		q = g_utf8_next_char (p);
@@ -305,7 +305,7 @@ _vte_ring_thaw_row (VteRing *ring, gulong position, VteRowData *row, gboolean do
 				}
 			} else {
 				ring->last_attr_text_start_offset = 0;
-				ring->last_attr.i = basic_cell.i.attr;
+				ring->last_attr = basic_cell.attr;
 			}
 		}
 		_vte_stream_truncate (ring->row_stream, position * sizeof (record));
@@ -326,7 +326,7 @@ _vte_ring_reset_streams (VteRing *ring, gulong position)
 	}
 
 	ring->last_attr_text_start_offset = 0;
-	ring->last_attr.i = basic_cell.i.attr;
+	ring->last_attr = basic_cell.attr;
 }
 
 long
@@ -942,13 +942,13 @@ _vte_ring_rewrap (VteRing *ring,
 			}
 			runlength = MIN(paragraph_len, attr_change.text_end_offset - text_offset);
 
-			if (G_UNLIKELY (attr_change.attr.s.columns == 0)) {
+			if (G_UNLIKELY (attr_change.attr.columns == 0)) {
 				/* Combining characters all fit in the current row */
 				text_offset += runlength;
 				paragraph_len -= runlength;
 			} else {
 				while (runlength) {
-					if (col >= columns - attr_change.attr.s.columns + 1) {
+					if (col >= columns - attr_change.attr.columns + 1) {
 						/* Wrap now, write the soft wrapped row's record */
 						new_record.soft_wrapped = 1;
 						_vte_stream_append(new_row_stream, (const char *) &new_record, sizeof (new_record));
@@ -981,7 +981,7 @@ _vte_ring_rewrap (VteRing *ring,
 						/* Process one character only. */
 						char textbuf[6];  /* fits at least one UTF-8 character */
 						int textbuf_len;
-						col += attr_change.attr.s.columns;
+						col += attr_change.attr.columns;
 						/* Find beginning of next UTF-8 character */
 						text_offset++; paragraph_len--; runlength--;
 						textbuf_len = MIN(runlength, sizeof (textbuf));
diff --git a/src/ring.h b/src/ring.h
index 84fea26..b56d82e 100644
--- a/src/ring.h
+++ b/src/ring.h
@@ -38,7 +38,7 @@ typedef struct _VteVisualPosition {
 
 typedef struct _VteCellAttrChange {
 	gsize text_end_offset;  /* offset of first character no longer using this attr */
-	VteIntCellAttr attr;
+	VteCellAttr attr;
 } VteCellAttrChange;
 
 
@@ -59,7 +59,7 @@ struct _VteRing {
 	/* Storage */
 	VteStream *attr_stream, *text_stream, *row_stream;
 	gsize last_attr_text_start_offset;
-	VteIntCellAttr last_attr;
+	VteCellAttr last_attr;
 	GString *utf8_buffer;
 
 	VteRowData cached_row;
diff --git a/src/vte.cc b/src/vte.cc
index d8fc4fc..3f2b9bb 100644
--- a/src/vte.cc
+++ b/src/vte.cc
@@ -269,7 +269,7 @@ VteTerminalPrivate::ring_remove(vte::grid::row_t position)
 void
 VteTerminalPrivate::reset_default_attributes()
 {
-        m_defaults = m_color_defaults = m_fill_defaults = basic_cell.cell;
+        m_defaults = m_color_defaults = m_fill_defaults = basic_cell;
 }
 
 //FIXMEchpe this function is bad
@@ -2217,7 +2217,7 @@ VteRowData *
 VteTerminalPrivate::ensure_cursor()
 {
 	VteRowData *row = ensure_row();
-        _vte_row_data_fill(row, &basic_cell.cell, m_screen->cursor.col);
+        _vte_row_data_fill(row, &basic_cell, m_screen->cursor.col);
 
 	return row;
 }
@@ -3056,7 +3056,7 @@ VteTerminalPrivate::insert_char(gunichar c,
                         _vte_row_data_insert (row, col + i, &m_color_defaults);
 	} else {
                 cleanup_fragments(col, col + columns);
-		_vte_row_data_fill (row, &basic_cell.cell, col + columns);
+		_vte_row_data_fill (row, &basic_cell, col + columns);
 	}
 
         attr = m_defaults.attr;
@@ -8533,7 +8533,7 @@ VteTerminalPrivate::determine_colors(VteCell const* cell,
                                      guint *fore,
                                      guint *back) const
 {
-	determine_colors(cell ? &cell->attr : &basic_cell.cell.attr,
+	determine_colors(cell ? &cell->attr : &basic_cell.attr,
                          highlight, false /* not cursor */,
                          fore, back);
 }
@@ -8544,7 +8544,7 @@ VteTerminalPrivate::determine_cursor_colors(VteCell const* cell,
                                             guint *fore,
                                             guint *back) const
 {
-	determine_colors(cell ? &cell->attr : &basic_cell.cell.attr,
+	determine_colors(cell ? &cell->attr : &basic_cell.attr,
                          highlight, true /* cursor */,
                          fore, back);
 }
diff --git a/src/vterowdata.h b/src/vterowdata.h
index c9f710e..2e73fd4 100644
--- a/src/vterowdata.h
+++ b/src/vterowdata.h
@@ -63,12 +63,6 @@ typedef struct _VteCellAttr {
 } VteCellAttr;
 G_STATIC_ASSERT (sizeof (VteCellAttr) == 8);
 
-typedef union _VteIntCellAttr {
-	VteCellAttr s;
-	guint64 i;
-} VteIntCellAttr;
-G_STATIC_ASSERT (sizeof (VteCellAttr) == sizeof (VteIntCellAttr));
-
 /*
  * VteCell: A single cell's data
  */
@@ -79,35 +73,24 @@ typedef struct _VTE_GNUC_PACKED _VteCell {
 } VteCell;
 G_STATIC_ASSERT (sizeof (VteCell) == 12);
 
-typedef union _VteIntCell {
-	VteCell cell;
-	struct _VTE_GNUC_PACKED {
-		guint32 c;
-		guint64 attr;
-	} i;
-} VteIntCell;
-G_STATIC_ASSERT (sizeof (VteCell) == sizeof (VteIntCell));
-
-static const VteIntCell basic_cell = {
+static const VteCell basic_cell = {
+	0,
 	{
-		0,
-		{
-			0, /* fragment */
-			1, /* columns */
-			0, /* bold */
-			0, /* italic */
-			VTE_DEFAULT_FG, /* fore */
-			VTE_DEFAULT_BG, /* back */
-
-			0, /* underline */
-			0, /* strikethrough */
-
-			0, /* reverse */
-			0, /* blink */
-			0, /* half */
-
-			0  /* invisible */
-		}
+		0, /* fragment */
+		1, /* columns */
+		0, /* bold */
+		0, /* italic */
+		VTE_DEFAULT_FG, /* fore */
+		VTE_DEFAULT_BG, /* back */
+
+		0, /* underline */
+		0, /* strikethrough */
+
+		0, /* reverse */
+		0, /* blink */
+		0, /* half */
+
+		0  /* invisible */
 	}
 };
 
diff --git a/src/vteseq.cc b/src/vteseq.cc
index c91beeb..663833a 100644
--- a/src/vteseq.cc
+++ b/src/vteseq.cc
@@ -1926,7 +1926,7 @@ VteTerminalPrivate::seq_tab()
 		 */
 
 		old_len = _vte_row_data_length (rowdata);
-                _vte_row_data_fill (rowdata, &basic_cell.cell, newcol);
+                _vte_row_data_fill (rowdata, &basic_cell, newcol);
 
 		/* Insert smart tab if there's nothing in the line after
 		 * us, not even empty cells (with non-default background
@@ -2963,7 +2963,7 @@ VteTerminalPrivate::seq_screen_alignment_test()
 		/* Fill this row. */
                 VteCell cell;
 		cell.c = 'E';
-		cell.attr = basic_cell.cell.attr;
+		cell.attr = basic_cell.attr;
 		cell.attr.columns = 1;
                 _vte_row_data_fill(rowdata, &cell, m_column_count);
                 emit_text_inserted();
