-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Use size_t for index / length types #6947
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
6a17714
to
02f30c9
Compare
if (i >= 0 && i < _currentArgCount) | ||
return _currentArgs[i].value; | ||
return emptyString; | ||
const String& ESP8266WebServerTemplate<ServerType>::arg(size_t i) const { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Signature change, this could be a breaking change. Either we wait for v3 or add a forwarder method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it is fully source compatible because signed integers can always be numerically promoted to unsigned integers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nevertheless, it can be a breaking change. Trivial example:
struct Base
{
void method(int a) {std::cout << "a=" << a << std::endl;}
};
struct Derived : Base
{
// void method(int a)
void method(size_t a)
{
char buffer[128] = {0};
sprintf(buffer, "%d", a);
std::cout << "buffer=" << buffer << std::endl;
Base::method(a);
}
};
int main()
{
Base base;
Derived derived;
base.method(3);
derived.method(-3);
}
The above will cause a warning, and if building with extra it will fail to compile. Similar will happen if a user has a derived class with a check like if (a < 0)
, which will also give a warning.
Then, although far less likely, there's a whole range of std::numeric_limits::blah() that could go wrong, as well as template stuff I don't really want to go into detail right now, which could result in straight up compilation errors.
Please beware signature changes. I agree with your intent, and I welcome the proposed change, but merging must be done with great care. We've been bitten by signature changes in the past.
The one place where a signature change is ok is in private methods, because those methods can't be called externally nor from derived classes. And even then there's friend objects to consider, if any.
if (i >= 0 && i < _currentArgCount) | ||
return _currentArgs[i].key; | ||
return emptyString; | ||
const String& ESP8266WebServerTemplate<ServerType>::argName(size_t i) const { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Signature change
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it is fully source compatible because signed integers can always be numerically promoted to unsigned integers.
} | ||
|
||
template <typename ServerType> | ||
int ESP8266WebServerTemplate<ServerType>::args() const { | ||
return _currentArgCount; | ||
size_t ESP8266WebServerTemplate<ServerType>::args() const { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Signature change. I'm not sure how to handle this case, though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The return value is not part of a signature so this is not really a signature change. and it fixes a problem in the API (which was a mix of integer and unsigned before)
if (i < _headerKeysCount) | ||
return _currentHeaders[i].value; | ||
return emptyString; | ||
const String& ESP8266WebServerTemplate<ServerType>::header(size_t i) const { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Signature change
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it is fully source compatible because signed integers can always be numerically promoted to unsigned integers.
02f30c9
to
c4deaef
Compare
I can add int overloads for the size_t versions if needed however I think it isn't needed (none of those are virtual so polymorphism mismatches are not likely) |
As I show in the trivial example in the review, polymorphism isn't the only thing to consider when changing a signature. A signature change in class methods is not as simple as it seems at first glance. |
@devyte lets step back for a bit.. are those assumptions/expectations documented somewhere so that I can see what is in line and what isn't? from my personal experience I any day prefer compile warnings/issues over things that pass compile perfectly but change behavior in subtle ways (maybe exploiting an undocumented behavior) and then break the app. What are the options? can I add a #ifdef please_be_compatible_with_version_26 ? kinda give people the option? or create a _v3 full fork that users can opt into and gives a preview (without stability guarantees) of what it will look like when 3.0.0 is released? |
@dirkmueller
It is part of semantic versioning, which we try to follow, although with some exceptions. To allow merging in for a minor/sub, proposed changes must not break current applications. The specifics are based on experience. Like I've said, we've been bitten before, and as repo maintainer I more or less know what to look for and point out by now.
In no way is it implied that this should happen. What we want to do is to keep current behavior AND not have compiler warnings/errors. We don't want to pave over subtle things that could break.
The options are what they have always been:
When a change in your PR is pointed as being breaking, you can choose to fix the PR to allow merging for a minor/sub, or you can choose to keep the PR pending for the next major. I think you already have one such pending PR, I remember targeting a PR from you for v3, something about constness. |
74895c8
to
7a767fb
Compare
@dirkmueller, what is the point of this PR? do you need larger size then int? |
7a767fb
to
34ad6ec
Compare
@JAndrassy main reason is correctness (avoid negative indizes being passed in causing a crash) and code reduction (don't need to check for negative indizes being passed in) |
@here can I do anything to get this PR merged? It is just a small bugfix plus code cleanup |
@dirkmueller we're now merging for v3, and it's ok to break things a bit there. Could you please resolve conflicts? |
yes, within the next day or so. |
34ad6ec
to
3bf880c
Compare
3bf880c
to
f755e3b
Compare
Would it be wise to use |
f755e3b
to
10e02e2
Compare
@d-a-v yes it would be wise, but it was previously objected to: #6947 (comment) I can change it either way. for now source compatibility wins. |
5bf59e7
to
9c2fbc9
Compare
While the API quirk remains until 3.x, we at least use size_t consistently internally which avoids bugs (missing handling of negative values) as well as reduces code (no need to check for negative values).
9c2fbc9
to
02968cc
Compare
PR size here would get smaller if #7558 is merged first. |
While the API quirk remains until 3.x, we at least use size_t consistently internally which avoids bugs (missing handling of negative values) as well as reduces code (no need to check for negative values).