Единственная причина, по которой они оба хорошо компилируются, заключается в том, что вы на самом деле не используете foo, поэтому не имеет значения, может ли компоновщик найти foo или нет (он никогда не пытается). (Или ваш компилятор / компоновщик - мусор. :))
Согласованный заголовок в порядке. Тот, в котором отсутствует const, не является и будет / должен привести к ошибкам, если что-то попытается использовать foo.
Если вы создадите какой-нибудь файл (не globals.cpp), который включает в себя globals.h и попытается использовать foo (например, просто добавьте строку с функцией "foo.c_str ();" в функцию), вы получите ссылку ошибка, потому что const std::string foo
не найдено.
Так и должно быть. Заголовок говорит обо всем, что хочет использовать foo, что он может только читать, но не изменять его. Вещи, которые включают заголовок globals.h, не имеют представления о том, что находится внутри globals.cpp; если вы хотите, чтобы они рассматривали объект как const, вы должны поместить эту информацию в файл, который они включают.