Я думаю, вы преувеличиваете статус этого мифического "правила". Гораздо чаще случается так, что функция возвращает неотрицательное значение в случае успеха, указывающее результат какого-либо вида (количество записанных / прочитанных / преобразованных байтов, текущая позиция, размер, значение следующего символа и т. Д.), И эти отрицательные значения, которые в противном случае не имеет смысла для интерфейса, зарезервированы для сигнализации об ошибках. С другой стороны, некоторые функции должны возвращать результаты без знака, но ноль никогда не имеет смысла как действительный результат, а затем ноль используется для сигнализации об ошибках.
Короче говоря, делайте все, что имеет смысл в приложении или библиотеке, которые вы разрабатываете, но стремитесь к согласованности. И я имею в виду согласованность с внешним кодом, а не только с вашим собственным кодом. Если вы используете сторонний или библиотечный код, соответствующий определенному соглашению, и ваш код разработан для тесной связи с этим сторонним кодом, возможно, имеет смысл следовать соглашениям этого кода, чтобы другие программисты, работающие над проектом, не надевались нежелательных сюрпризов.
И, наконец, как уже говорили другие, независимо от вашего соглашения, задокументируйте его!